diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..31a89864 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +src/configuration.php \ No newline at end of file diff --git a/build.bat b/build.bat deleted file mode 100644 index aa68451f..00000000 --- a/build.bat +++ /dev/null @@ -1,12 +0,0 @@ -:: Easy!Appointments -:: -:: This scripts creates a new build for Easy!Appointments. This build -:: can be used for distributing a new version of the project. -TITLE Easy!Appointments -del /s/f/q "build\*.*" -for /f %%f in ('dir /ad /b "build"') do rd /s /q "build%f" -mkdir "build" -copy /y "release-notes.txt" "build\release-notes.txt" -xcopy /s/e/y "src" "build" -xcopy /y "build\configuration-sample.php" "build\configuration.php" -del "build\configuration-sample.php" \ No newline at end of file diff --git a/db/easy_appointments.sql b/db/easy_appointments.sql deleted file mode 100644 index 87057c97..00000000 --- a/db/easy_appointments.sql +++ /dev/null @@ -1,329 +0,0 @@ --- phpMyAdmin SQL Dump --- version 3.5.1 --- http://www.phpmyadmin.net --- --- Φιλοξενητής: localhost --- Χρόνος δημιουργίας: 24 Σεπ 2013 στις 11:03:51 --- Έκδοση διακομιστή: 5.5.24-log --- Έκδοση PHP: 5.4.3 - -SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- Βάση: `easy_appointments` --- - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_appointments` --- - -CREATE TABLE IF NOT EXISTS `ea_appointments` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `book_datetime` datetime DEFAULT NULL, - `start_datetime` datetime DEFAULT NULL, - `end_datetime` datetime DEFAULT NULL, - `notes` text, - `hash` text, - `is_unavailable` tinyint(4) DEFAULT '0', - `id_users_provider` bigint(20) unsigned DEFAULT NULL, - `id_users_customer` bigint(20) unsigned DEFAULT NULL, - `id_services` bigint(20) unsigned DEFAULT NULL, - `id_google_calendar` text, - PRIMARY KEY (`id`), - KEY `id_users_customer` (`id_users_customer`), - KEY `id_services` (`id_services`), - KEY `id_users_provider` (`id_users_provider`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=42 ; - --- --- Άδειασμα δεδομένων του πίνακα `ea_appointments` --- - -INSERT INTO `ea_appointments` (`id`, `book_datetime`, `start_datetime`, `end_datetime`, `notes`, `hash`, `is_unavailable`, `id_users_provider`, `id_users_customer`, `id_services`, `id_google_calendar`) VALUES -(21, '2013-09-13 12:02:18', '2013-09-13 15:00:00', '2013-09-13 17:00:00', '', 'be278cf3c1d617fc372d89d75d5fd26d', 0, 2, 21, 4, 'e2c7abe3eket7ip9c58lllt3c8'), -(37, '2013-09-13 13:47:54', '2013-09-14 11:30:00', '2013-09-14 13:30:00', 'Γυμναστήριο ', '3ace1513fdf92a4983b7ae719a8475b5', 1, 2, NULL, NULL, 'cqm0t14p50d0917ghkirtruuno'), -(38, '2013-09-13 13:47:54', '2013-09-14 15:00:00', '2013-09-14 18:00:00', 'Ε!Α ', '3ace1513fdf92a4983b7ae719a8475b5', 1, 2, NULL, NULL, 'vs0btdvi34t73rvkeubh77ln40'), -(39, '2013-09-13 15:39:44', '2013-09-13 17:00:00', '2013-09-13 17:20:00', 'This is a test appt.', '6fd60f567310511d8f2fb4ff4c787d5e', 0, 2, 22, 3, NULL), -(40, '2013-09-13 15:50:14', '2013-09-14 10:00:00', '2013-09-14 11:00:00', 'heart decease', '39b81301e5bb1a82f77bd23d07ec63ce', 0, 4, 23, 2, NULL), -(41, '2013-09-23 17:04:53', '2013-09-24 09:45:00', '2013-09-24 10:15:00', '', '4c782e7af14a98e03657cc64c9a4fe61', 0, 25, 26, 4, NULL); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_roles` --- - -CREATE TABLE IF NOT EXISTS `ea_roles` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(256) DEFAULT NULL, - `slug` varchar(256) DEFAULT NULL, - `is_admin` tinyint(4) DEFAULT NULL COMMENT '0', - `appointments` int(4) DEFAULT NULL COMMENT '0', - `customers` int(4) DEFAULT NULL COMMENT '0', - `services` int(4) DEFAULT NULL COMMENT '0', - `users` int(4) DEFAULT NULL COMMENT '0', - `system_settings` int(4) DEFAULT NULL COMMENT '0', - `user_settings` int(11) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; - --- --- Άδειασμα δεδομένων του πίνακα `ea_roles` --- - -INSERT INTO `ea_roles` (`id`, `name`, `slug`, `is_admin`, `appointments`, `customers`, `services`, `users`, `system_settings`, `user_settings`) VALUES -(1, 'Administrator', 'admin', 1, 15, 15, 15, 15, 15, NULL), -(2, 'Provider', 'provider', 0, 15, 15, 0, 0, 0, NULL), -(3, 'Customer', 'customer', 0, 0, 0, 0, 0, 0, NULL), -(4, 'Secretary', 'secretary', 0, 15, 15, 0, 0, 15, NULL); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_secretaries_providers` --- - -CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` ( - `id_users_secretary` bigint(20) unsigned NOT NULL, - `id_users_provider` bigint(20) unsigned NOT NULL, - PRIMARY KEY (`id_users_secretary`,`id_users_provider`), - KEY `fk_ea_secretaries_providers_1` (`id_users_secretary`), - KEY `fk_ea_secretaries_providers_2` (`id_users_provider`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - --- --- Άδειασμα δεδομένων του πίνακα `ea_secretaries_providers` --- - -INSERT INTO `ea_secretaries_providers` (`id_users_secretary`, `id_users_provider`) VALUES -(20, 2), -(20, 3); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_services` --- - -CREATE TABLE IF NOT EXISTS `ea_services` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(256) DEFAULT NULL, - `duration` int(11) DEFAULT NULL, - `price` decimal(10,2) DEFAULT NULL, - `currency` varchar(32) DEFAULT NULL, - `description` text, - `id_service_categories` bigint(20) unsigned DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `id_service_categories` (`id_service_categories`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; - --- --- Άδειασμα δεδομένων του πίνακα `ea_services` --- - -INSERT INTO `ea_services` (`id`, `name`, `duration`, `price`, `currency`, `description`, `id_service_categories`) VALUES -(2, 'Heart Examination', 30, '40.00', 'Euro', 'Checkup for heart problems.', NULL), -(3, 'Neurological Examination', 20, '35.00', 'Euro', 'Neurological tests for the patient.', NULL), -(4, 'General Examination', 30, '30.00', 'Euro', 'General patient examination. Includes blood, pressure and eyes tests.', 2); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_services_providers` --- - -CREATE TABLE IF NOT EXISTS `ea_services_providers` ( - `id_users` bigint(20) unsigned NOT NULL, - `id_services` bigint(20) unsigned NOT NULL, - PRIMARY KEY (`id_users`,`id_services`), - KEY `id_services` (`id_services`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- --- Άδειασμα δεδομένων του πίνακα `ea_services_providers` --- - -INSERT INTO `ea_services_providers` (`id_users`, `id_services`) VALUES -(3, 2), -(4, 2), -(2, 3), -(3, 3), -(2, 4), -(25, 4); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_service_categories` --- - -CREATE TABLE IF NOT EXISTS `ea_service_categories` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(256) DEFAULT NULL, - `description` text, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ; - --- --- Άδειασμα δεδομένων του πίνακα `ea_service_categories` --- - -INSERT INTO `ea_service_categories` (`id`, `name`, `description`) VALUES -(2, 'General Services', 'Contains the general services of our company.'), -(5, 'test1', 'test1'), -(7, 'test2', 'test2'); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_settings` --- - -CREATE TABLE IF NOT EXISTS `ea_settings` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(512) DEFAULT NULL, - `value` longtext, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ; - --- --- Άδειασμα δεδομένων του πίνακα `ea_settings` --- - -INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES -(1, 'company_name', 'Easy!Appointmnets & Co'), -(2, 'company_working_plan', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}'), -(3, 'company_email', 'info@alextselegidis.com'), -(8, 'company_link', 'http://easyappointments.org'), -(9, 'book_advance_timeout', '30'), -(15, NULL, NULL); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_users` --- - -CREATE TABLE IF NOT EXISTS `ea_users` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `first_name` varchar(256) DEFAULT NULL, - `last_name` varchar(512) DEFAULT NULL, - `email` varchar(512) DEFAULT NULL, - `mobile_number` varchar(128) DEFAULT NULL, - `phone_number` varchar(128) DEFAULT NULL, - `address` varchar(256) DEFAULT NULL, - `city` varchar(256) DEFAULT NULL, - `state` varchar(128) DEFAULT NULL, - `zip_code` varchar(64) DEFAULT NULL, - `notes` text, - `id_roles` bigint(20) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `id_roles` (`id_roles`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ; - --- --- Άδειασμα δεδομένων του πίνακα `ea_users` --- - -INSERT INTO `ea_users` (`id`, `first_name`, `last_name`, `email`, `mobile_number`, `phone_number`, `address`, `city`, `state`, `zip_code`, `notes`, `id_roles`) VALUES -(2, 'Ned', 'Janger', 'alextselegidis@gmail.com', '659875666', '785448465', 'Kloesel', 'Berlin', '', '23980', '', 2), -(3, 'Urlich', 'Setzel', 'u.setzel@piorin.com', '23908252398', '20923798723', 'Groundliche Str. 23', 'Munich', 'Bayern', '86895', '', 2), -(4, 'Brandon', 'Clod', 'b.clod@besters.org', '239072439', '858754487', 'Wellin Str 8', 'Plymouth', '', '20940', '', 2), -(18, 'Tod', 'Cliffer', 'info@alextselegidis.com', '987568857', '875986878', 'Yourd Str 98', 'Blackpool', 'MyState', '85874', 'This is a test admin record used for testing the project. All the data are not real.', 1), -(20, 'Sonia', 'Sterling', 's.sterling@reo.com', '584256658', '4265462587', '', '', '', '', '', 4), -(21, 'Alex', 'Tselegidis', 'info@alextselegidis.com', NULL, '98765465712', '', '', NULL, '', '', 3), -(22, 'John', 'Doe', 'john.doe@oizent.com', NULL, '8757595445', 'Orizend 51', 'London', NULL, '56648', 'Test customer record.', 3), -(23, 'James', 'Goern', 'james.goern@softiner.com', NULL, '98654869544', 'Ureklin 09', 'New York', NULL, '56987', NULL, 3), -(24, 'test', 'test', 'test@test.com', '233252325', '234523342', 'test', 'test', '', '', '', 1), -(25, 'Jason', 'Brandon', 'j.brandon@solyell.uk', '7899875789', '7854789897', 'Hilton Str. 52', 'Michigan', '', '87786', 'This is a test provider. All data are fictional.', 2), -(26, 'John', 'Doe', 'j.doe@doens.com', NULL, '897987657', '', '', NULL, '', NULL, 3); - --- -------------------------------------------------------- - --- --- Δομή πίνακα για τον πίνακα `ea_user_settings` --- - -CREATE TABLE IF NOT EXISTS `ea_user_settings` ( - `id_users` bigint(20) unsigned NOT NULL, - `username` varchar(256) DEFAULT NULL, - `password` varchar(512) DEFAULT NULL, - `salt` varchar(512) DEFAULT NULL, - `working_plan` text, - `notifications` tinyint(4) DEFAULT '0', - `google_sync` tinyint(4) DEFAULT '0', - `google_token` text, - `sync_past_days` int(11) DEFAULT '5', - `sync_future_days` int(11) DEFAULT '5', - PRIMARY KEY (`id_users`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- --- Άδειασμα δεδομένων του πίνακα `ea_user_settings` --- - -INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `salt`, `working_plan`, `notifications`, `google_sync`, `google_token`, `sync_past_days`, `sync_future_days`) VALUES -(2, 'ned.janger', '6ad76c5daab92f2aaf9f9d725cb72bc2774fdb4ac2172828a8f1c6aa69e9b0d1', 'edd27f8204a0cc47c60a3cd031fe03211be2561c76b334678e0f982ef582bf6e', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 1, 0, NULL, 5, 5), -(3, 'u.setzel', 'f00e1e6f3780859b40645be7ff8e91878ea2679eb62fbc45a8bff1243338b741', '7f8231dd21df341c651522e4091637e6a93d160decb6a7a99bd08a5dc5d947c8', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 1, 0, NULL, 5, 5), -(4, 'b.clod', '811acf5c450e0eb2866a17cdc3701a0b1fddb98ea2065e91259e8e6ce9b678b6', 'edd27f8204a0cc47c60a3cd031fe03211be2561c76b334678e0f982ef582bf6e', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 0, 0, NULL, 5, 5), -(18, 'admin', '9e81360f0a631fe7e49e9d051b05c581a0f17575ca043a340be4441e166de821', 'd6ac3bfb4e6d9f82ec54e606852a9afbe8697696cddd28f30423eddf98762f41', NULL, 0, 0, NULL, 5, 5), -(20, 's.sterling', '8746aff0a416b63e71046d6a6adc6e2fd9de4a1cf4de0281e5b5f60ba8ae4451', 'edd27f8204a0cc47c60a3cd031fe03211be2561c76b334678e0f982ef582bf6e', NULL, 0, 0, NULL, 5, 5), -(24, 'test', 'd1dce587f7eefdb93adceb4e8903d72036bf97d37482b9c7b1d5f08353d061f3', 'd6ac3bfb4e6d9f82ec54e606852a9afbe8697696cddd28f30423eddf98762f41', NULL, 0, 0, NULL, 5, 5), -(25, 'j.brandon', 'dc93d098ccbcaa871e4adcc2dd770d71f6fca7a24dbd635e00006b5075dc2db1', '7f8231dd21df341c651522e4091637e6a93d160decb6a7a99bd08a5dc5d947c8', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 1, 0, NULL, 5, 5); - --- --- Περιορισμοί για άχρηστους πίνακες --- - --- --- Περιορισμοί για πίνακα `ea_appointments` --- -ALTER TABLE `ea_appointments` - ADD CONSTRAINT `ea_appointments_ibfk_2` FOREIGN KEY (`id_users_customer`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - ADD CONSTRAINT `ea_appointments_ibfk_3` FOREIGN KEY (`id_services`) REFERENCES `ea_services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - ADD CONSTRAINT `ea_appointments_ibfk_4` FOREIGN KEY (`id_users_provider`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - --- --- Περιορισμοί για πίνακα `ea_secretaries_providers` --- -ALTER TABLE `ea_secretaries_providers` - ADD CONSTRAINT `fk_ea_secretaries_providers_1` FOREIGN KEY (`id_users_secretary`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - ADD CONSTRAINT `fk_ea_secretaries_providers_2` FOREIGN KEY (`id_users_provider`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - --- --- Περιορισμοί για πίνακα `ea_services` --- -ALTER TABLE `ea_services` - ADD CONSTRAINT `ea_services_ibfk_1` FOREIGN KEY (`id_service_categories`) REFERENCES `ea_service_categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE; - --- --- Περιορισμοί για πίνακα `ea_services_providers` --- -ALTER TABLE `ea_services_providers` - ADD CONSTRAINT `ea_services_providers_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - ADD CONSTRAINT `ea_services_providers_ibfk_2` FOREIGN KEY (`id_services`) REFERENCES `ea_services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - --- --- Περιορισμοί για πίνακα `ea_users` --- -ALTER TABLE `ea_users` - ADD CONSTRAINT `ea_users_ibfk_1` FOREIGN KEY (`id_roles`) REFERENCES `ea_roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - --- --- Περιορισμοί για πίνακα `ea_user_settings` --- -ALTER TABLE `ea_user_settings` - ADD CONSTRAINT `ea_user_settings_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/doc/E!A UML.zargo b/doc/E!A UML.zargo deleted file mode 100644 index 8da82d34..00000000 Binary files a/doc/E!A UML.zargo and /dev/null differ diff --git a/doc/code/generate-docs.bat b/doc/code/generate-docs.bat deleted file mode 100644 index b50d3eff..00000000 --- a/doc/code/generate-docs.bat +++ /dev/null @@ -1,17 +0,0 @@ -:: Easy!Appointments -:: -:: This script generates the code documentation of the system -:: using the jsdoc and apigen tools. In order to run properly -:: the system should have Java and ApiGen installed already. -:: -:: THIS SCRIPT RUNS ONLY ON WINDOWS. YOU MIGHT NEED TO CHANGE -:: THE APIGEN SCRIPT PATH TO WHERE YOUR INSTALLATION EXISTS. -:: -:: You might also need to change the mermory_limit setting on your -:: php.ini file to successfully generate the php documentation. -::@echo off -TITLE Easy!Appointments -DEL "js\*.*" /Q -DEL "php\*.*" /Q -CALL ..\..\rsc\scripts\jsdoc\jsdoc ..\..\src\assets\js -d js -CALL C:\wamp\bin\php\php5.4.3\apigen --source ..\..\src\application\controllers --source ..\..\src\application\models --destination php \ No newline at end of file diff --git a/doc/thesis-topic.pdf b/doc/thesis-topic.pdf deleted file mode 100644 index 345ad31c..00000000 Binary files a/doc/thesis-topic.pdf and /dev/null differ diff --git a/doc/thesis/compile.bat b/doc/thesis/compile.bat deleted file mode 100644 index 0b4c5334..00000000 --- a/doc/thesis/compile.bat +++ /dev/null @@ -1,51 +0,0 @@ -:: =============================================== -:: GENERATES THE EASY!APPOINTMENTS THESIS DOCUMENT -:: =============================================== - -:: Run Cleanup -call:cleanupq - -:: Run XeLaTex on main file. -xelatex thesis.tex --quiet -biber thesis --quiet - -:: If you are using multibib the following will run bibtex on all aux files -:: FOR /R . %%G IN (*.aux) DO bibtex %%G -xelatex thesis.tex --quiet -xelatex thesis.tex --quiet - -:: Run Cleanup -call:cleanup - -:: Open PDF (Script updated based on comments by 'menfeser' -:: START "" "C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe" %2.pdf -START "" thesis.pdf - -:: Cleanup Function -:cleanup -del *.log -del *.dvi -del *.aux -del *.bbl -del *.blg -del *.brf -del *.out -del *.log -del *.bcf -del *.xml -del *.toc -del *.lof - -del includes\*.log -del includes\*.dvi -del includes\*.aux -del includes\*.bbl -del includes\*.blg -del includes\*.brf -del includes\*.out -del includes\*.log -del includes\*.bcf -del includes\*.xml -del includes\*.toc - -goto:eof \ No newline at end of file diff --git a/doc/thesis/compile.sh b/doc/thesis/compile.sh deleted file mode 100644 index 73e34799..00000000 --- a/doc/thesis/compile.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -## =============================================== -## GENERATES THE EASY!APPOINTMENTS THESIS DOCUMENT -## =============================================== - -clear -xelatex --output-format=pdf thesis.tex --quiet -bibtex thesis.tex -xelatex --output-format=pdf thesis.tex --quiet - -rm *.log -rm *.dvi -rm *.aux -rm *.bbl -rm *.blg -rm *.brf -rm *.out -rm *.log -rm *.bcf -rm *.xml -rm *.toc - -rm includes\*.log -rm includes\*.dvi -rm includes\*.aux -rm includes\*.bbl -rm includes\*.blg -rm includes\*.brf -rm includes\*.out -rm includes\*.log -rm includes\*.bcf -rm includes\*.xml -rm includes\*.toc - -echo "Process Ended" diff --git a/doc/thesis/diagrams/ea-ad-book-appointment.io b/doc/thesis/diagrams/ea-ad-book-appointment.io deleted file mode 100644 index f586be02..00000000 --- a/doc/thesis/diagrams/ea-ad-book-appointment.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-ad-install-application.io b/doc/thesis/diagrams/ea-ad-install-application.io deleted file mode 100644 index cc991ab5..00000000 --- a/doc/thesis/diagrams/ea-ad-install-application.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-ad-provider-available-hours.io b/doc/thesis/diagrams/ea-ad-provider-available-hours.io deleted file mode 100644 index 97dee117..00000000 --- a/doc/thesis/diagrams/ea-ad-provider-available-hours.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-ad-sync-appointments.io b/doc/thesis/diagrams/ea-ad-sync-appointments.io deleted file mode 100644 index f73618ee..00000000 --- a/doc/thesis/diagrams/ea-ad-sync-appointments.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-cd-backend-settings.io b/doc/thesis/diagrams/ea-cd-backend-settings.io deleted file mode 100644 index d8d2fe02..00000000 --- a/doc/thesis/diagrams/ea-cd-backend-settings.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-cd-backend-users.io b/doc/thesis/diagrams/ea-cd-backend-users.io deleted file mode 100644 index f89f2ecd..00000000 --- a/doc/thesis/diagrams/ea-cd-backend-users.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-domain-model.io b/doc/thesis/diagrams/ea-domain-model.io deleted file mode 100644 index 8aa23adc..00000000 --- a/doc/thesis/diagrams/ea-domain-model.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-er.io b/doc/thesis/diagrams/ea-er.io deleted file mode 100644 index a460bc0b..00000000 --- a/doc/thesis/diagrams/ea-er.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-gantt-analytic.gantter b/doc/thesis/diagrams/ea-gantt-analytic.gantter deleted file mode 100644 index 1277e4bf..00000000 --- a/doc/thesis/diagrams/ea-gantt-analytic.gantter +++ /dev/null @@ -1 +0,0 @@ -2013-11-08T10:37:082013-11-08T10:55:0412013-04-11T08:00:002013-11-04T17:00:0003

1

08:00:0017:00:00480
2400
201111Standard1-1102108:00:0012:00:0013:00:0017:00:003108:00:0012:00:0013:00:0017:00:004108:00:0012:00:0013:00:0017:00:005108:00:0012:00:0013:00:0017:00:006108:00:0012:00:0013:00:0017:00:0070224-Hours1-11100:00:0000:00:002100:00:0000:00:003100:00:0000:00:004100:00:0000:00:005100:00:0000:00:006100:00:0000:00:007100:00:0000:00:003Night Shift1-1102123:00:0000:00:003100:00:0003:00:0004:00:0008:00:0023:00:0000:00:004100:00:0003:00:0004:00:0008:00:0023:00:0000:00:005100:00:0003:00:0004:00:0008:00:0023:00:0000:00:006100:00:0003:00:0004:00:0008:00:0023:00:0000:00:007100:00:0003:00:0004:00:0008:00:0000ea-gantt.gnt02013-11-08T08:37:080002013-04-11T08:00:002013-11-04T17:00:00PT1184H0M0S39PT0H0M0S00101102013-04-11T08:00:002013-11-04T17:00:002013-09-26T08:00:002013-11-04T17:00:0000051Θεσσαλονίκη, Ελλάδα0

-1

0
https://code.google.com/p/easy-appointments/
Easy!Appointments - Google Code
00null
101Σχεδίαση Εφαρμογής02013-11-08T08:43:181112013-04-11T08:00:002013-04-15T17:00:00PT24H0M0S39PT0H0M0S1010002013-04-11T08:00:002013-04-15T17:00:002013-10-31T08:00:002013-11-04T17:00:000004

-1

2013-04-11T08:00:00000null
112Υλοποίηση Κράτησης Ραντεβού02013-11-08T08:43:532212013-04-16T08:00:002013-05-16T17:00:00PT184H0M0S39PT0H0M0S1010002013-04-16T08:00:002013-05-16T17:00:002013-10-03T08:00:002013-11-04T17:00:000006

-1

2013-05-16T17:00:00000null
123Υλοποίηση Διαχείρισης Ραντεβού02013-11-08T08:45:173312013-05-20T08:00:002013-06-26T17:00:00PT224H0M0S39PT0H0M0S1010002013-05-20T08:00:002013-06-26T17:00:002013-09-26T08:00:002013-11-04T17:00:000006

-1

2013-06-26T17:00:00000null
134Υλοποίηση Συγχρονισμού Google Calendar02013-11-08T08:46:174412013-07-02T08:00:002013-07-15T17:00:00PT80H0M0S39PT0H0M0S1010002013-07-02T08:00:002013-07-15T17:00:002013-10-22T08:00:002013-11-04T17:00:000006

-1

2013-07-15T17:00:00000null
145Διαχείριση Πελατών02013-11-08T08:47:285512013-07-15T08:00:002013-07-15T17:00:00PT8H0M0S39PT0H0M0S1010002013-07-15T08:00:002013-07-15T17:00:002013-11-04T08:00:002013-11-04T17:00:000004

-1

2013-07-15T08:00:00000null
156Διαχείριση Υπηρεσιών02013-11-08T08:47:516612013-07-15T08:00:002013-07-26T17:00:00PT80H0M0S39PT0H0M0S1010002013-07-15T08:00:002013-07-26T17:00:002013-10-22T08:00:002013-11-04T17:00:000006

-1

2013-07-27T17:00:00000null
167Διαχείριση Χρηστών02013-11-08T08:48:307712013-08-26T08:00:002013-09-03T17:00:00PT56H0M0S39PT0H0M0S1010002013-08-26T08:00:002013-09-03T17:00:002013-10-25T08:00:002013-11-04T17:00:000006

-1

2013-09-03T17:00:00000null
178Ρυθμίσεις Συστήματος02013-11-08T08:49:398812013-09-16T08:00:002013-09-20T17:00:00PT40H0M0S39PT0H0M0S1010002013-09-16T08:00:002013-09-20T17:00:002013-10-29T08:00:002013-11-04T17:00:000006

-1

2013-09-20T17:00:00000null
189Login/Logout/Forgot Password02013-11-08T08:50:349912013-10-11T08:00:002013-10-11T17:00:00PT8H0M0S39PT0H0M0S1010002013-10-11T08:00:002013-10-11T17:00:002013-11-04T08:00:002013-11-04T17:00:000004

-1

2013-10-11T08:00:00000null
1910Οδηγός Εγκατάστασης Εφαρμογής02013-11-08T08:51:49101012013-10-16T08:00:002013-10-17T17:00:00PT16H0M0S39PT0H0M0S1010002013-10-16T08:00:002013-10-17T17:00:002013-11-01T08:00:002013-11-04T17:00:000006

-1

2013-10-17T17:00:00000null
2011Συγγραφή Βιβλίου02013-11-08T08:52:24111112013-10-22T08:00:002013-11-04T17:00:00PT80H0M0S39PT0H0M0S1010012013-10-22T08:00:002013-11-04T17:00:002013-10-22T08:00:002013-11-04T17:00:000006

-1

2013-11-04T17:00:00000null
\ No newline at end of file diff --git a/doc/thesis/diagrams/ea-gantt-simple.ods b/doc/thesis/diagrams/ea-gantt-simple.ods deleted file mode 100644 index 51c61c39..00000000 Binary files a/doc/thesis/diagrams/ea-gantt-simple.ods and /dev/null differ diff --git a/doc/thesis/diagrams/ea-sd-save-appointment.io b/doc/thesis/diagrams/ea-sd-save-appointment.io deleted file mode 100644 index 99b7985e..00000000 --- a/doc/thesis/diagrams/ea-sd-save-appointment.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-sd-sync-appointment.io b/doc/thesis/diagrams/ea-sd-sync-appointment.io deleted file mode 100644 index df341823..00000000 --- a/doc/thesis/diagrams/ea-sd-sync-appointment.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/diagrams/ea-system-architecture.io b/doc/thesis/diagrams/ea-system-architecture.io deleted file mode 100644 index ae617769..00000000 --- a/doc/thesis/diagrams/ea-system-architecture.io +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/doc/thesis/images/ad-book-appointment.png b/doc/thesis/images/ad-book-appointment.png deleted file mode 100644 index 0d5e02b4..00000000 Binary files a/doc/thesis/images/ad-book-appointment.png and /dev/null differ diff --git a/doc/thesis/images/ad-install-application.png b/doc/thesis/images/ad-install-application.png deleted file mode 100644 index 1cac3476..00000000 Binary files a/doc/thesis/images/ad-install-application.png and /dev/null differ diff --git a/doc/thesis/images/ad-provider-available-hours.png b/doc/thesis/images/ad-provider-available-hours.png deleted file mode 100644 index d1235cbd..00000000 Binary files a/doc/thesis/images/ad-provider-available-hours.png and /dev/null differ diff --git a/doc/thesis/images/ad-sync-appointments.png b/doc/thesis/images/ad-sync-appointments.png deleted file mode 100644 index 2bfd68fa..00000000 Binary files a/doc/thesis/images/ad-sync-appointments.png and /dev/null differ diff --git a/doc/thesis/images/backend-calendar.jpg b/doc/thesis/images/backend-calendar.jpg deleted file mode 100644 index 2a3ae2dc..00000000 Binary files a/doc/thesis/images/backend-calendar.jpg and /dev/null differ diff --git a/doc/thesis/images/backend-providers.jpg b/doc/thesis/images/backend-providers.jpg deleted file mode 100644 index a70c4a75..00000000 Binary files a/doc/thesis/images/backend-providers.jpg and /dev/null differ diff --git a/doc/thesis/images/backend-settings.jpg b/doc/thesis/images/backend-settings.jpg deleted file mode 100644 index c1e5d8c5..00000000 Binary files a/doc/thesis/images/backend-settings.jpg and /dev/null differ diff --git a/doc/thesis/images/book-appointment.jpg b/doc/thesis/images/book-appointment.jpg deleted file mode 100644 index d8e93eaa..00000000 Binary files a/doc/thesis/images/book-appointment.jpg and /dev/null differ diff --git a/doc/thesis/images/cd-backend-settings.png b/doc/thesis/images/cd-backend-settings.png deleted file mode 100644 index 506b8e1c..00000000 Binary files a/doc/thesis/images/cd-backend-settings.png and /dev/null differ diff --git a/doc/thesis/images/cd-backend-users.png b/doc/thesis/images/cd-backend-users.png deleted file mode 100644 index 16950a0a..00000000 Binary files a/doc/thesis/images/cd-backend-users.png and /dev/null differ diff --git a/doc/thesis/images/domain-model.png b/doc/thesis/images/domain-model.png deleted file mode 100644 index 0b5eac68..00000000 Binary files a/doc/thesis/images/domain-model.png and /dev/null differ diff --git a/doc/thesis/images/ea-unit-testing.png b/doc/thesis/images/ea-unit-testing.png deleted file mode 100644 index ff474352..00000000 Binary files a/doc/thesis/images/ea-unit-testing.png and /dev/null differ diff --git a/doc/thesis/images/er.png b/doc/thesis/images/er.png deleted file mode 100644 index cd03623a..00000000 Binary files a/doc/thesis/images/er.png and /dev/null differ diff --git a/doc/thesis/images/gantt-simple.jpg b/doc/thesis/images/gantt-simple.jpg deleted file mode 100644 index aca30329..00000000 Binary files a/doc/thesis/images/gantt-simple.jpg and /dev/null differ diff --git a/doc/thesis/images/gantt-simple.png b/doc/thesis/images/gantt-simple.png deleted file mode 100644 index b143fa18..00000000 Binary files a/doc/thesis/images/gantt-simple.png and /dev/null differ diff --git a/doc/thesis/images/google-calendar-api.png b/doc/thesis/images/google-calendar-api.png deleted file mode 100644 index 2d347b6e..00000000 Binary files a/doc/thesis/images/google-calendar-api.png and /dev/null differ diff --git a/doc/thesis/images/mvc.png b/doc/thesis/images/mvc.png deleted file mode 100644 index c1744438..00000000 Binary files a/doc/thesis/images/mvc.png and /dev/null differ diff --git a/doc/thesis/images/sd-save-appointment.png b/doc/thesis/images/sd-save-appointment.png deleted file mode 100644 index 1aca40bb..00000000 Binary files a/doc/thesis/images/sd-save-appointment.png and /dev/null differ diff --git a/doc/thesis/images/sd-sync-appointment.png b/doc/thesis/images/sd-sync-appointment.png deleted file mode 100644 index 7933e70c..00000000 Binary files a/doc/thesis/images/sd-sync-appointment.png and /dev/null differ diff --git a/doc/thesis/images/system-architecture.png b/doc/thesis/images/system-architecture.png deleted file mode 100644 index a64d8a9b..00000000 Binary files a/doc/thesis/images/system-architecture.png and /dev/null differ diff --git a/doc/thesis/includes/conclusions.tex b/doc/thesis/includes/conclusions.tex deleted file mode 100644 index 95a0c919..00000000 --- a/doc/thesis/includes/conclusions.tex +++ /dev/null @@ -1,45 +0,0 @@ -\chapter{Συμπεράσματα} -Το αποτέλεσμα της εκπόνησης της εργασίας είναι ένα πλήρης σύστημα διαχείρισης ραντεβού το οποίο μπορεί να διαμορφωθεί επαρκώς έτσι ώστε να καλύψει τις ανάγκες οποιασδήποτε επιχείρισης ανεξαρτήτου ειδικότητας και μεγέθους. Ο αρχικός σχεδιασμός αποδείχθηκε σωστός και έτσι το τελικό προϊόν λογισμικού πληροί τις απαιτήσεις για τις οποίες αναπτύχθηκε. - -\section{Προβλήματα} -Σε αυτήν την ενότητα περιγράφονται τα σημαντικότερα προβλήματα που αντιμετωπίστηκαν κατά την διάρκεια της ανάπτυξης του Easy!Appointments. Επεξηγούνται οι αποφάσεις που πάρθηκαν στην κάθε περίπτωση και αναλύονται οι λύσεις που χρησιμοποιήθηκαν. - -\subsection{Διαχείριση χρόνου} -Σημαντικότερο πρόβλημα σχετικά με την υλοποίηση της εφαρμογής ήταν η χρονική καθυστέρηση μιας και ανάμεσα στην ανάληψη της εργασίας και την περαίωση της, πραγματοποιήθηκε η πρακτική άσκηση σε εταιρεία πληροφορικής καθώς και εργασία εκτός σχολής με άλλες εταιρείες του ίδιου τομέα. Οι εξωτερικές υποχρεώσεις αυτές αποσπούσαν την συνεχή και ομαλή ανάπτυξη, κάτι που συνεχώς διασπούσε τον ειρμό και τον δημιουργικό οίστρο. Συμπέρασμα αυτού του σημαντικού προβλήματος είναι ότι θα πρέπει να γίνεται σαφής και ορθός προγραμματισμός του χρόνου υλοποίησης ενός έργου γιατί διαφορετικά οι πιθανότητες για χαμηλότερη ποιότητα υπηρεσίας ή ακόμα και αποτυχίας του έργου αυξάνονται εκθετικά. Σε αυτό μπορεί να συντελέσει και η πληθώρα των εφαρμογών οι οποίες αποσκοπούν στην αποδοτικότερη διαχείριση έργων λογισμικού οι οποίες είναι διαθέσιμες είτε δωρεάν, είτε έναντι αμοιβής. - -\subsection{Συγχρονισμός δεδομένων με το Google Calendar} -Όσον αφορά την συνεργασία του συστήματος με την υπηρεσία Google Calendar αλλά και γενικότερα με άλλες πιθανές υπηρεσίες το ζήτημα παραμένει στο πως θα παραμείνουν τα δεδομένα ακέραια και ενημερωμένα και στα δύο συστήματα, όταν δεν υπάρχει ένα κοινό μέσο αποθήκευσης. Το θέμα γιγαντώνεται μάλιστα όταν δεν υπάρχει πρόσβαση στον κώδικα του ενός από τα δύο συστήματα έτσι ώστε να δημιουργηθεί μια "γέφυρα δεδομένων". Για την επίλυση αυτού του θέματος ήταν αναγκαίο να δημιουργηθεί ένας αλγόριθμος συγχρονισμού ο οποίος θα ενεργοποιούνταν από την πλευρά του Easy!Appointments και θα αναλάμβανε την ενημέρωση και τον δύο συστημάτων με τα τελευταία δεδομένα. Για αυτόν τον σκοπό θα έπρεπε να καταγραφούν και να υλοποιηθούν κάποιοι κανόνες συγχρονισμού οι οποίοι θα μετέφεραν επιτυχώς τα ραντεβού αμφίδρομα και στα δύο συστήματα. Στις περιπτώσεις όπου η μεταφορά αυτή θα ήταν αδύνατη (σύγκρουση δεδομένων) ο χρήστης θα έπρεπε να αποφασίσει ποια εκδοχή των δεδομένων θα υπερισχύσει στο τέλος. - -\subsection{Διαχωρισμός δικαιωμάτων χρηστών} -Ένα ακόμα πρόβλημα που αντιμετωπίστηκε κατά την διάρκεια την ανάπτυξης του έργου ήταν ο διαχωρισμός των δικαιωμάτων των χρηστών μέσα στο σύστημα. Ο κάθε χρήστης αναλόγως το είδος του (διαχειριστής, πάροχος, γραμματέας) έχει διαφορετικές δυνατότητες και δικαιώματα στα δεδομένα που αποθηκεύονται από το σύστημα. Αυτό συμβαίνει γιατί στις περισσότερες περιπτώσεις θα πρέπει να τηρηθεί η ιεραρχία της επιχείρησης αλλά και επίσης γιατί θα πρέπει να διασφαλιστεί η ακεραιότητα των δεδομένων από τυχόν εσφαλμένες ενέργειες χρηστών σε βασικές ρυθμίσεις του συστήματος. Για τις κυριότερες ρυθμίσεις απαιτούνται τα δικαιώματα διαχειριστή και έτσι το σύστημα χρειάζεται απαραιτήτως πάντα έναν χρήστη διαχειριστή (ο χρήστης που δημιουργείται κατά την εγκατάσταση είναι ουσιαστικά ο πρώτος διαχειριστής της εφαρμογής). Για να λυθεί αυτό το πρόβλημα η εγγραφή του κάθε χρήστη στην βάση δεδομένων συνδέεται με έναν ρόλο ο οποίος περιέχει τα δικαιώματα που του αντιστοιχούν. Έτσι για παράδειγμα ένας χρήστης που προορίζεται για πάροχος υπηρεσίας, θα έχει τα δικαιώματα που αντιστοιχούν στον ρόλο "Πάροχος Υπηρεσίας" όπως αυτά είναι αποθηκευμένα στην βάση δεδομένων. Έτσι κάθε φορά που συνδέεται ένας χρήστης στο διαχειριστικό κομμάτι της εφαρμογής τα δεδομένα σχετικά με τα δικαιώματα του και τον ρόλο του διαβάζονται από σελίδα σε σελίδα και η εφαρμογή μπορεί και γνωρίζει με ποιόν τρόπο θα πρέπει να εμφανιστούν τα δεδομένα και ποιες ενέργειες είναι διαθέσιμες στην κάθε περίπτωση. - -\section{Εξέλιξη της εφαρμογής} -Όπως και σε κάθε έργο λογισμικού, υπάρχουν πολλά πράγματα τα οποία μπορούν να εξελιχθούν και να βελτιωθούν καθώς και δυνατότητες οι οποίες μπορούν να προστεθούν για να κάνουν την εφαρμογή πιο εύχρηστη και αποδοτικότερη. Οι βελτιώσεις αυτές γίνονται στην φάση της συντήρησης και επέκτασης σταδιακά, με σκοπό την ύπαρξη ενός ενημερωμένου προϊόντος στην αγορά. Με αυτόν τον τρόπο οι εταιρείες θα μπορούν να εμπιστεύονται την εν λόγω εφαρμογή και να την χρησιμοποιούν ως το δικό τους εργαλείο διαχείρισης των ραντεβού. Παρακάτω περιγράφονται κάποια σημεία στα οποία θα μπορούσε να εξελιχθεί μελλοντικά το σύστημα που παράχθηκε. - -\subsection{Mobile design} -Με την πάροδο του χρόνου όλο και περισσότερες "έξυπνες" συσκευές βρίσκονται στα χέρια των καταναλωτών και έτσι δημιουργείται η ανάγκη για χρήση των διαδικτυακών εφαρμογών από οθόνες που έχουν διαφορετικά μεγέθη οθονών. Εφόσον η σχεδίαση για όλες τις διαστάσεις οθονών υπολογιστή έχουν καλυφθεί, το επόμενο βήμα είναι να σχεδιαστεί το σύστημα για κινητές συσκευές και tablet. Με αυτόν τον τρόπο θα μπορούν οι χρήστες του Easy!Appointments να χρησιμοποιούν το σύστημα από το κινητό τους πολύ πιο άνετα και έτσι να είναι πάντα ενημερωμένοι σχετικά με τα ραντεβού τους όπου και αν βρίσκονται. Προϋπόθεση για αυτό πάντα είναι μια ενεργή σύνδεση με το διαδίκτυο. Για να υλοποιηθεί αυτή η δυνατότητα θα χρειαστεί να γραφεί CSS κώδικας ο οποίος να εμφανίζει την εφαρμογή διαφορετικά σε κινητές συσκευές. - -\subsection{Μετάφραση της διεπαφής χρήστη} -Η πρώτη υλοποίηση του συστήματος έχει γίνει εξολοκλήρου στην αγγλική γλώσσα όπως και με τα περισσότερα συστήματα που απευθύνονται σε ένα ευρύ καταναλωτικό κοινό. Το Easy!Appointments δέχεται κείμενο και σε άλλες γλώσσες (χρησιμοποιείται το encoding UTF-8) αλλά η διεπαφή, τα μηνύματα και τα αντικείμενα ελέγχου είναι όλα στα Αγγλικά. Για να γίνει πιο εύκολη η χρήση της εφαρμογής και από ανθρώπους οι οποίοι δεν είναι τόσο εξοικειωμένοι με αυτήν την γλώσσα θα πρέπει να μεταφραστεί όλο το σύστημα και σε άλλες κοινές γλώσσες. Για να επιτευχθεί αυτό στην συγκεκριμένη περίπτωση θα πρέπει να χρησιμοποιηθεί μια συγκεκριμένη τεχνική, όπως ενδεικνύεται από τον ιστότοπο του κατασκευαστή του CodeIgniter. - -\subsection{Αναφορές δεδομένων} -Το σύστημα μέσω της λειτουργίας του κρατάει διάφορα δεδομένα (ραντεβού, πελάτες, πάροχοι κτλ). Καλό θα ήταν αυτά τα δεδομένα να μπορούν να εξαχθούν με κάποιον τρόπο έτσι ώστε να μπορέσουν να χρησιμοποιηθούν και με άλλους τρόπους. Μια περίπτωση χρήσης θα ήταν η εξαγωγή των σημερινών ραντεβού ενός πάροχου σε μια εκτυπώσιμη αναφορά έτσι ώστε να μπορεί ο χρήστης να την τυπώσει και να την έχει ως λίστα στο γραφείο. Μια άλλη περίπτωση χρήσης θα ήταν να εκτυπωθούν τα στοιχεία ενός πελάτη καθώς και το ιστορικό των ραντεβού του. Οι αναφορές αυτές είναι πολύ χρήσιμες γιατί μπορούν να αναδείξουν γρήγορα δεδομένα και μάλιστα σε εκτυπώσιμη μορφή, κάτι που χρειάζονται ακόμα πολλές εταιρείες. - -\subsection{Στατιστικές πληροφορίες} -Μια χρήσιμη μελλοντική δυνατότητα θα ήταν η συλλογή στατιστικών πληροφοριών σχετικά με τα ραντεβού που κλίνονται στο σύστημα. Από αυτήν την διαδικασία θα μπορούσαν να βγουν σημαντικές πληροφορίες όπως το ποια υπηρεσία ή πάροχος προτιμάται πιο συχνά, ποιες μέρες έχουν τα περισσότερα ραντεβού, πόσο συχνά ακυρώνονται τα ραντεβού και σε πόσο χρονικό διάστημα πριν. Αυτές οι πληροφορίες είναι πολύ σημαντικές για μια εταιρεία η οποία λειτουργεί με κρατήσεις ραντεβού γιατί έτσι μπορεί να γνωρίζει με ποιόν τρόπο λειτουργεί το πελατειακό κοινό της και έτσι να λειτουργεί αναλόγως για να παρέχει καλύτερη εξυπηρέτηση. Ένα παράδειγμα θα ήταν η περίπτωση ενός μεγάλου κομμωτηρίου στην οποία οι πελάτες θα κρατούσαν πάρα πολλά ραντεβού το Σάββατο κάθε εβδομάδας, γιατί πιθανόν έχουν περισσότερο χρόνο. Τα στατιστικά (εκτός της πείρας) θα έδειχναν την αυξημένη κίνηση του Σαββάτου και έτσι ο διαχειριστής θα είχε διαθέσιμους όλους του πάροχους προς ραντεβού, για να μπορέσει να καλυφθεί το κοινό όσο καλύτερα γίνεται. - -\subsection{Δημιουργία RESTful υπηρεσίας} -Κάθε μεγάλο διαδικτυακό σύστημα παρέχει και μια RESTful υπηρεσία η οποία μπορεί να απαντάει με δεδομένα σε διάφορες κλήσεις που της γίνονται, εφόσον βέβαια έχει πιστοποιηθεί ο client που επικοινωνεί μαζί τους. Με αυτόν τον τρόπο θα μπορούν άλλοι προγραμματιστές να φτιάχνουν εφαρμογές οι οποίες θα επικοινωνούν με το Easy!Appointments και θα διαχειρίζονται τα δεδομένα του συστήματος. Η υλοποίηση αυτής της δυνατότητας θα βοηθούσε πολύ την εξέλιξη και την χρήση του Easy!Appointments γιατί από εδώ και πέρα διάφορες εφαρμογές θα υλοποιούνταν κάνοντας δυνατή την χρήση των δεδομένων σε πολλές διαφορετικές περιστάσεις. Κάτι που είναι πάρα πολύ χρήσιμο για κάθε επαγγελματία (παραδείγματος χάρη η χρήση πελατών από CRM εφαρμογή). - -\subsection{Βελτίωση κώδικα} -Τελευταίο αλλά και όχι λιγότερο σημαντικό είναι η συνεχής βελτίωση και ενημέρωση του κώδικα έτσι ώστε να είναι πάντα στην καλύτερη δυνατή κατάσταση. Καθώς εξελίσσεται ένα σύστημα λογισμικού είναι απαραίτητο να βελτιώνεται ο κώδικας και η δομή του. Επίσης είναι απαραίτητο να ενημερώνονται και τα εξωτερικά εργαλεία τα οποία χρησιμοποιούνται έτσι ώστε να διασφαλίζεται η ασφάλεια και η ποιότητα του συστήματος. Κατά καιρούς εμφανίζονται διάφορες ενημερώσεις ασφαλείας αλλά και διορθώσεων σφαλμάτων σε αυτά τα framework (CodeIgniter, jQuery κτλ) τα οποία θα χρειαστεί να συμπεριληφθούν και στο Easy!Appointments. Κάθε φορά που ο χρήστης λαμβάνει μια νέα έκδοση της εφαρμογής θα πρέπει ο κώδικας που την απαρτίζει να βρίσκεται σε πολύ καλή κατάσταση, να έχει ελεγχθεί και να λειτουργεί σωστά έτσι ώστε να εμπνέει εμπιστοσύνη προς τους χρήστες. - -\section{Πληροφορίες} -Η διαχείριση του έργου έγινε στην υπηρεσία Google Code και ο κώδικας είναι διαθέσιμος στην διεύθυνση \url{https://code.google.com/p/easy-appointments/}. Υπάρχει επίσης και η επίσημη ιστοσελίδα του Easy!Appointments στην διεύθυνση \url{http://easyappointments.org}. -\newline -\begin{figure}[H] -\centering -\includegraphics[width=150mm]{images/gantt-simple.jpg} -\caption{Χρονοδιάγραμμα Υλοποίησης (Gantt)} -\label{gantt-simple} -\end{figure} \ No newline at end of file diff --git a/doc/thesis/includes/external-tools.tex b/doc/thesis/includes/external-tools.tex deleted file mode 100644 index 2c840f0e..00000000 --- a/doc/thesis/includes/external-tools.tex +++ /dev/null @@ -1,40 +0,0 @@ -%% ΕΞΩΤΕΡΙΚΑ ΕΡΓΑΛΕΙΑ -%% Σε αυτό το κεφάλαιο γίνεται περιγραφή των υπόλοιπων εξωτερικών -%% εργαλείων που χρησιμοποιήθηκαν από για την υλοποίηση του συστήματος -%% κρατήσεων ραντεβού. - -\chapter{Εξωτερικά Εργαλεία} -Εκτός του Calendar API και των βιβλιοθηκών που παρέχει η Google, έχουν χρησιμοποιηθεί και κάποια άλλα εργαλεία ανάπτυξης λογισμικού τα οποία βοήθησαν στην άρτια και ποιοτικότερη παραγωγή του συστήματος κρατήσεων ραντεβού. Τα εργαλεία αυτά είναι όλα ανοιχτού κώδικα (open source) και έχουν στόχο να βοηθήσουν τον προγραμματιστή να επικεντρωθεί περισσότερο σε αυτό που έχει να κάνει και όχι τόσο στα τετριμμένα πράγματα τα οποία αποσπούν μεγάλο χρονικό διάστημα άσκοπα. Εν ολίγοις πρόκειται για ένα σύνολο από διάφορα framework τα οποία είναι πολύ χρήσιμα για οποιαδήποτε ανάπτυξη λογισμικού. - -\section{CodeIgniter} -Το CodeIgniter είναι ένα PHP framework το οποίο έχει ως στόχο την αποδοτικότητα και την ταχύτητα μιας και καταναλώνει πολύ λίγους υπολογιστικούς πόρους σε αντίθεση με άλλα βοηθητικά συστήματα του είδους του. Θετικό στοιχείο είναι ότι είναι πολύ απλό στην χρήση, δίνει την δυνατότητα στον προγραμματιστή να διαμορφώσει τον πυρήνα του καταπώς τον βολεύει και βασίζεται στην αρχιτεκτονική MVC (Model - View - Controller). Όντας έργο ανοιχτού λογισμικού κατέχει μια μεγάλη κοινότητα που το υποστηρίζει και επίσης προσφέρει μια καλά ενημερωμένη γνωσιακή βάση, η οποία μπορεί να καθοδηγήσει τον προγραμματιστή στο πως θα χρησιμοποιήσει το framework. - -Η αρχιτεκτονική MVC είναι η πλέον διαδεδομένη κυρίως στις διαδικτυακές εφαρμογές αφού αποσκοπεί στην καλύτερη οργάνωση και συντήρηση του κώδικα. Ουσιαστικά πρόκειται για τον διαχωρισμό της εφαρμογής σε τρία μέρη: -\begin{enumerate} -\item Models: Περιέχουν συναρτήσεις και μεθόδους που αλληλεπιδρούν με την βάση δεδομένων. Χρησιμοποιούνται σε διάφορες περιπτώσεις από τους Controllers. Με αυτόν τον τρόπο επιτυγχάνεται η επαναχρησιμοποίηση ενός μέρους του κώδικα, κάτι το οποίο είναι πολύ σημαντικό στην αρχιτεκτονική ενός συστήματος. -\item Views: Τα views είναι τα κομμάτια κώδικα τα οποία παράγουν το αποτέλεσμα το οποίο βλέπει ο χρήστης κάθε φορά. Στόχος τους είναι απλώς να δείξουν και όχι να υπολογίσουν ή να φέρουν κάποια δεδομένα (αυτό είναι δουλειά των άλλων δυο τμημάτων της αρχιτεκτονικής). Κάθε φορά που χρειάζεται να αλλάξει κάτι στην εμφάνιση του συστήματος μπορεί να γίνει αλλαγή στο αντίστοιχο view χωρίς να επηρεαστούν τα άλλα συστήματα. -\item Controllers: Το μέρος αυτό του συστήματος αναλαμβάνει να οργανώσει τα άλλα δυο. Κάθε φορά που πρέπει να παραχθεί μια σελίδα η διαδικασία θα ξεκινήσει από τον αντίστοιχο controller. Αυτός στην συνέχεια θα καλέσει τις απαραίτητες συναρτήσεις και θα παρέχει τα δεδομένα που απαιτεί το view για να εμφανιστεί σωστά η σελίδα. -\end{enumerate} - -\begin{figure} -\centering -\includegraphics[width=70mm]{images/mvc.png} -\caption{Αρχιτεκτονική MVC} -\label{mvc} -\end{figure} - -Το σύστημα που υλοποιήθηκε χρησιμοποιεί το CodeIgniter για την κάλυψη των βασικών εργασιών έτσι ώστε να υπάρχει η δομή MVC στον κώδικα. Επίσης γίνεται χρήση της ενσωματωμένης βιβλιοθήκης επικοινωνίας με την βάση δεδομένων. Εκτός αυτών των δύο, ο υπόλοιπος κώδικας έχει γραφεί κανονικά και τηρεί τις προϋποθέσεις της πτυχιακής εργασίας. - -\section {jQuery \& jQuery UI} -Ένα μεγάλο μέρος των σύγχρονων διαδικτυακών εφαρμογών βασίζει την λειτουργία του σε κώδικα JavaScript έτσι ώστε να κάνει το λογισμικό πιο φιλικό προς τον χρήστη. Διάφορες βιβλιοθήκες έχουν δημιουργηθεί τα τελευταία χρόνια που στόχο έχουν την εξέλιξη και την αποδοτικότερη χρήση της γλώσσας JavaScript. Η πιο δημοφιλής από όλες αυτές τις βιβλιοθήκες είναι η jQuery η οποία συνοδεύεται από το jQuery UI, ένα framework για την παραγωγή στοιχείων ελέγχου (controls) στα οποία μπορεί ο κάθε χρήστης να εκτελέσει διάφορες ενέργειες. Το jQuery έχει καταφέρει να απλοποιήσει την συγγραφή JavaScript κώδικα και επιπλέον παρέχει στην διάθεση του προγραμματιστή έτοιμες ρουτίνες animation και διαφόρων άλλων ενεργειών, οι οποίες διαφορετικά θα καταλάμβαναν αρκετό χρόνο για την υλοποίηση τους. Πρόκειται για μια βιβλιοθήκη ανοιχτού λογισμικού η οποία υποστηρίζεται από μια πολύ μεγάλη κοινότητα προγραμματιστών. Υπάρχει επίσης πληθώρα πρόσθετων (plugins) με λειτουργίες οι οποίες δεν είναι διαθέσιμες στην βασική βιβλιοθήκη. - -Η jQuery ουσιαστικά λειτουργεί σαν ένα επίπεδο πάνω από την JavaScript βοηθώντας τον προγραμματιστή να γράψει διάφορες δομές κώδικα πιο γρήγορα και οργανωμένα. Ο κώδικας που γράφεται είναι πάλι JavaScript οπότε είναι πολύ εύκολο στον καθένα να χρησιμοποιήσει την βιβλιοθήκη. Στόχος της είναι η πιο εύκολη περιήγηση στα αντικείμενα μιας σελίδας (DOM elements), η εύκολη δημιουργία εφέ κινήσεων τα οποία προσδίδουν πολύ αισθητικά σε μια ιστοσελίδα, η ευκολότερη χρήση της τεχνολογίας AJAX, μιας τεχνολογίας η οποία χρησιμοποιείται όλο και περισσότερο από τα σύγχρονα συστήματα. - -Το σύστημα που παράχθηκε χρησιμοποιεί αυτήν την βιβλιοθήκη για τον προγραμματισμό του client-side μέρους της εφαρμογής. Ανάλογα με την κάθε περίσταση, μερικές φορές είναι αποδοτικότερο και χρησιμότερο να χρησιμοποιηθεί JavaScript έναντι της PHP και για αυτόν τον λόγο επιλέχθηκε το jQuery Framework ως εργαλείο κατά την υλοποίηση του συστήματος. - -\section {Bootstrap} -Το Bootstrap είναι ένα ολοκληρωμένο CSS Framework με την προσθήκη κάποιων βιβλιοθηκών JavaScript έτσι ώστε να προσφέρει μερικές επιπλέον δυνατότητες. Έχει κατασκευαστεί από την εταιρεία πίσω από την σελίδα κοινωνικής δικτύωσης Twitter και χρησιμοποιείται από αυτήν ως βάση για την υλοποίηση της. Η εταιρεία έχει διαθέσει το framework ως ανοιχτό λογισμικό και οι προγραμματιστές μπορούν να το χρησιμοποιήσουν ελεύθερα στις σελίδες τους. Η ίδια η εταιρεία επωφελείται μέσω της συμμετοχής της κοινότητας για να αναπτύξει περαιτέρω το framework. - -Το Bootstrap περιέχει έτοιμο κώδικα CSS ο οποίος ακολουθεί την μεθοδολογία παραγωγής responsive ιστοσελίδων. Με την έννοια αυτή εννοείται ότι η μορφοποίηση των σελίδων στοχεύει στο να είναι συμβατή με οποιαδήποτε συσκευή, λειτουργικό σύστημα και περιηγητή ιστού. Είναι πολύ σημαντικό για την αναγνωρισιμότητα και ευχρηστία μιας εφαρμογής το να είναι διαθέσιμη σε οποιοδήποτε μηχάνημα υποστηρίζει τα τελευταία standards του ιστού. Το JavaScript μέρος του framework χρησιμοποιεί το jQuery για την υλοποίηση διαφόρων τεχνικών (πχ εμφάνιση παραθύρου διαλόγου). - -Στην παραγωγή του συστήματος κρατήσεων ραντεβού χρησιμοποιήθηκε ως η βάση για τη μορφοποίηση και κάποιες μέθοδοι JavaScript φάνηκαν αρκετά χρήσιμα σε κάποια σημεία. Στην συνέχεια με βάση αυτά γράφτηκαν ξεχωριστά αρχεία CSS και JavaScript τα οποία αποτελούν το τελικό αποτέλεσμα που έπρεπε να επιτευχθεί. \ No newline at end of file diff --git a/doc/thesis/includes/google-calendar-api.tex b/doc/thesis/includes/google-calendar-api.tex deleted file mode 100644 index b64902a8..00000000 --- a/doc/thesis/includes/google-calendar-api.tex +++ /dev/null @@ -1,153 +0,0 @@ -%% ΠΕΡΙΓΡΑΦΗ ΤΟΥ GOOGLE CALENDAR API -%% Σε αυτό το κεφάλαιο περιγράφεται το Google Calendar API -%% και το πως χρησιμοποιείται από το σύστημα για να πραγματοποιηθεί -%% η διαδικασία του συγχρονισμού. - -\chapter{Google Calendar API} -Το Ημερολόγιο της Google είναι μια διαδικτυακή εφαρμογή που επιτρέπει στους χρήστες της να αποθηκεύουν και να διαχειρίζονται τα ραντεβού και τα συμβάντα τους σε ένα όμορφο περιβάλλον. Εκτός αυτού, υπάρχουν πολλές πρόσθετες δυνατότητες όπως ο συγχρονισμός ημερολογίου με κάποια άλλη εφαρμογή ή η κοινή χρήση ενός ημερολογίου από -πολλά άτομα. - -Όπως και με τα περισσότερα προϊόντα της Google παρέχονται εργαλεία με τα οποία μπορούν οι προγραμματιστές να επικοινωνήσουν και να λάβουν δεδομένα από τις υπηρεσίες της εταιρείας. Με -αυτόν τον τρόπο είναι δυνατή η ανάπτυξη εφαρμογών οι οποίες διαχειρίζονται αυτά τα δεδομένα, διευκολύνοντας έτσι τον χρήστη. - -\begin{figure}[h] -\centering -\includegraphics[width=150mm]{images/google-calendar-api.png} -\caption{Ιστότοπος περιγραφής του Google Calendar API.} -\label{google-calendar-api} -\end{figure} - -Το Google Calendar API (Application Programming Interface) -είναι μια πλατφόρμα διαχείρισης συμβάντων ενός ημερολογίου από την Google. Επιτρέπει στον προγραμματιστή να πραγματοποιήσει λειτουργίες προσθήκης, επεξεργασίας, διαγραφής και αναζήτησης συμβάντων μέσω ενός RESTful στυλ κλήσεων προς τον server. - -Με την έννοια RESTful (Representional State Transfer) εννοείται ένας από τους πιο δημοφιλής τρόπους επικοινωνίας στον παγκόσμιο ιστό. Η επικοινωνία γίνεται με την χρήση ειδικών αιτήσεων προς τους servers οι οποίοι με την σειρά τους είναι σε θέση να τις επεξεργαστούν και να επιστρέψουν δεδομένα πίσω στους clients. Οι μέθοδοι αιτήσεων που είναι διαθέσιμες είναι: -\begin{enumerate} -\item GET -\item POST -\item PUT -\item DELETE -\end{enumerate} - -Πρακτικά η μέθοδος επικοινωνίας RESTFul μπορεί να χρησιμοποιηθεί από οποιοδήποτε σύστημα υποστηρίζει το πρωτόκολλο HTTP. Για να διευκολύνει όμως η Google τους προγραμματιστές έχει αναπτύξει βιβλιοθήκες κώδικα σε διάφορες γλώσσες προγραμματισμού (PHP, Java, .NET, Ruby κτλ) οι οποίες περιέχουν έτοιμες μεθόδους επικοινωνίας με τις υπηρεσίες της. Έτσι διευκολύνεται πολύ η διαδικασία ανάπτυξης μιας εφαρμογής που βασίζεται πάνω στα δεδομένα των χρηστών της Google. - -Για να αποτραπεί η υπερβολική χρήση της υπηρεσίας Calendar, η εταιρεία έχει θέσει ένα υπέρτατο όριο 10.000 request την ημέρα. Αν κάποια εταιρεία ξεπεράσει αυτό το όριο τότε θα χρειαστεί να πληρώσει κάποιο αντίτιμο για να μπορέσει να συνεχίσει κανονικά την χρήση. Για αυτό τον λόγο είναι και απαραίτητο οποιοσδήποτε client χρησιμοποιεί το Calendar API, να έχει πρώτα δημιουργήσει ένα API Key μέσω της σελίδας API Console που προσφέρει η Google. - -\section {Περιγραφή του Calendar API} -Το Ημερολόγιο της Google είναι ένα πολύ δυνατό και ευέλικτο εργαλείο. Οι χρήστες μπορούν να βλέπουν το ίδιο ημερολόγιο σε οποιαδήποτε συσκευή βρίσκονται έχοντας απλώς σύνδεση με το διαδίκτυο (για να είναι εφικτή η λήψη των δεδομένων από την υπηρεσία). Όλες οι εφαρμογές αυτές χρησιμοποιούν το API για να υλοποιήσουν τις βασικές λειτουργίες ενός ημερολογίου, δηλαδή την διαχείριση και την εύκολη εύρεση συμβάντων που είναι καταχωρημένα στο Google Calendar. Αφού γίνουν οι αλλαγές αυτές θα χρειαστεί να εκτελεστεί η διαδικασία του συγχρονισμού έτσι ώστε τα νέα δεδομένα να είναι και στις υπόλοιπες εφαρμογές που έχουν πρόσβαση στο ημερολόγιο. - -Στην ευρεία χρήση της υπηρεσίας συντελεί το ότι η πλατφόρμα του ημερολογίου είναι συμβατή με διάφορες γλώσσες προγραμματισμού και έτσι μπορούν να υλοποιηθούν εφαρμογές για όλες τις συσκευές με εξελιγμένο λειτουργικό σύστημα (Windows, Linux, Mac OS, Android, iOS, Windows Phone κτλ). - -Οι βασικές έννοιες του συστήματος ενός ημερολογίου είναι: - -\begin{itemize} -\item Συμβάν (Event) - αντιπροσωπεύει ένα συμβάν στο ημερολόγιο το οποίο έχει τίτλο, περιγραφή, ημερομηνία και συμμετέχοντες. - -\item Ημερολόγιο (Calendar) - αντιπροσωπεύει ένα ημερολόγιο το οποίο περιέχει πολλά συμβάντα. Ένας χρήστης μπορεί να έχει πολλά ημερολόγια. Περιέχει επιπλέον πληροφορίες όπως η περιγραφή του ημερολογίου, ο ιδιοκτήτης κτλ. - -\item Λίστα Ημερολογίων (Calendar List) - αντιπροσωπεύει μια λίστα με όλα τα ημερολόγια ενός χρήστη της υπηρεσίας αυτής. - -\item Ρύθμιση (Setting) - αντιπροσωπεύει μια επιλογή του χρήστη, η οποία επηρεάζει τον τρόπο λειτουργίας της υπηρεσίας (πχ ρύθμιση ζώνης ώρας). - -\item ACL (Access Control Rule) - αντιπροσωπεύει έναν κανόνα πρόσβασης του ημερολογίου (όπως παραδείγματος χάρη το αν το ημερολόγιο είναι δημόσιο ή ιδιωτικό). - -\item Χρώμα (Color) - αντιπροσωπεύει το χρώμα για κάποια στοιχεία στο περιβάλλον χρήστη της εφαρμογής και τα συμβάντα. - -\item Ελεύθερος / Απασχολημένος (Free / Busy) - αντιπροσωπεύει μια χρονική περίοδο στο ημερολόγιο όπου ο χρήστης είναι είτε απασχολημένος είτε ελεύθερος. Αν είναι απασχολημένος δεν μπορούν να υπάρχουν συμβάντα -σε αυτό το διάστημα. -\end{itemize} - -Το API της Google λειτουργεί με “resources” και “collections” για να χειριστεί τις προαναφερθέντες έννοιες. Ένα resource αντιπροσωπεύει μια συγκεκριμένη οντότητα η οποία περιέχει δεδομένα για την εφαρμογή. Πολλά resource μαζί απαρτίζουν ένα collection το οποίο περιέχει πολλές χρήσιμες μεθόδους μαζικής διαχείρισης δεδομένων. - -Οι προγραμματιστές διαμορφώνουν τον κωδικά τους έτσι ώστε να είναι συμβατός με αυτήν την δομή και έτσι η επικοινωνία με την υπηρεσία της Google να είναι ευκολότερη. - -\section {Πως χρησιμοποιείται} -Η χρήση του API μπορεί να γίνει απευθείας με κλήσεις RESTful προς τον server της Google, είτε με χρήση κάποιων από τις έτοιμες βιβλιοθήκες που παρέχει η εταιρεία. Επίσης είναι απαραίτητη η ύπαρξη ενός λογαριασμού στην Google καθώς και η καταχώρηση του project στο Google API Console έτσι ώστε να πάρει ο προγραμματιστής ένα API Key, ένα κλειδί το οποίο είναι απαραίτητο για την χρήση της υπηρεσίας. - -Αν ο προγραμματιστής επιλέξει την χρήση της RESTful μεθόδου επικοινωνίας θα χρειαστεί να στέλνει request σε διάφορα URL και έτσι να παίρνει απαντήσεις με τα δεδομένα που χρειάζεται. Όλες οι απαντήσεις είναι σε JSON μορφή οπότε θα χρειαστεί να τις αναλύσει (parse) πριν τις χρησιμοποιήσει στην εφαρμογή του. - -Δείγματα από URL για την κλήση διαφόρων μεθόδων: - -\begin{lstlisting}[breaklines=true] -https://www.googleapis.com/calendar/v3/lists/calendarListID/calendar?parameters -https://www.googleapis.com/calendar/v3/users/userID/lists?parameters -\end{lstlisting} - -Αντιθέτως με την χρήση των έτοιμων βιβλιοθηκών οι διαδικασίες επικοινωνίας είναι έτοιμες και ο προγραμματιστής μπορεί να πετύχει την επικοινωνία με τους servers της Google γρηγορότερα και ευκολότερα. -Υπάρχουν βιβλιοθήκες για την Java, την PHP, την Python, το .NET περιβάλλον και την Ruby και πολλές άλλες γλώσσες και τεχνολογίες. - -Αφού γίνει λήψη των βιβλιοθηκών και συμπερίληψη στον κώδικα του project, μπορούν να χρησιμοποιηθούν μέσα από τον κώδικα: - -\begin{lstlisting} -require_once "../src/apiClient.php"; -require_once "../src/contrib/apiCalendarService.php"; -\end{lstlisting} - -Στην συνέχεια είναι απαραίτητο να γίνει ρύθμιση κάποιων παραμέτρων έτσι ώστε να μπορέσει να γίνει χρήση της υπηρεσίας: - -\begin{lstlisting}[breaklines=true] -global $apiConfig; - -$apiConfig = array( - // Site name to show in Google's OAuth authentication screen - 'site_name' => 'www.example.org', - - // OAuth2 Setting, you can get these keys on the API Access tab on - // the Google APIs Console - 'oauth2_client_id' => 'YOUR_CLIENT_ID', - 'oauth2_client_secret' => 'YOUR_CLIENT_SECRET', - 'oauth2_redirect_uri' => 'YOUR_REDIRECT_URL', - - // The developer key; you get this from the Google APIs Console - 'developer_key' => 'YOUR_DEVELOPER_KEY', - ... - - // Which Authentication, Storage and HTTP IO classes to use. - 'authClass' => 'apiOAuth2', - .... - - // Definition of service specific values like scopes, OAuth token URLs, etc - 'services' => array( - 'calendar' => array('scope' => 'https://www.googleapis.com/auth/calendar'), - ) -); -\end{lstlisting} - -Έπειτα θα χρειαστεί να γίνει εκκίνηση του service και να ολοκληρωθεί η διαδικασία πιστοποίησης (authenticate) με την χρήση του API Key που αντιστοιχεί στην εφαρμογή. - -\begin{lstlisting}[breaklines=true] -setUseObjects(true); -$service = new apiCalendarService($apiClient); - -if (isset($_SESSION['oauth_access_token'])) { - $apiClient->setAccessToken($_SESSION['oauth_access_token']); -} else { - $token = $apiClient->authenticate(); - $_SESSION['oauth_access_token'] = $token; -} -... -\end{lstlisting} - -Με αυτόν τον τρόπο εκτελούνται οι διαδικασίες ανταλλαγής δεδομένων μεταξύ του Google Calendar και του συστήματος του προγραμματιστή. - -\section{Συγχρονισμός ραντεβού} -Ο συγχρονισμός δεδομένων μεταξύ δυο συστημάτων είναι μια περίπλοκη και πολλές φορές υποτιμημένη διαδικασία, διότι ο προγραμματιστής έχει να κάνει αρκετή δουλειά έτσι ώστε να καταφέρει να γεφυρώσει και τις δυο πηγές δεδομένων με τον καλύτερο δυνατό τρόπο. Το αποτέλεσμα δεν μπορεί ποτέ να είναι 100\% επιτυχές διότι μερικές φορές τα δεδομένα και οι αλλαγές μπορεί να έρχονται σε σύγκρουση (conflict) και έτσι θα χρειαστεί να παρθούν αποφάσεις είτε με βάση κάποιους κανόνες προτεραιότητας, είτε από τον ίδιο τον χρήστη για το ποια αλλαγή θα υπερισχύσει εν τέλη. Το πράγμα μάλιστα δυσκολεύει περισσότερο όταν δεν υπάρχει πρόσβαση στον κώδικα του ενός από τα δύο συστήματα (πχ Google Calendar) και όλη η διαδικασία θα πρέπει να τρέξει από την μια πλευρά. - -Στην περίπτωση του Easy!Appointments έχει υλοποιηθεί μια διαδικασία η οποία συγχρονίζει τα ραντεβού και τα συμβάντα του συστήματος με αυτά του Google Calendar. Η διαδικασία αυτή εκτελείται όταν δημιουργούνται συγκεκριμένα συμβάντα (πχ. προσθήκη ραντεβού) και φέρνει και τα δύο ημερολόγια στην ίδια κατάσταση. Ο συγχρονισμός εκτελείται κάθε φορά για το πλάνο ενός πάροχου υπηρεσιών και εφόσον έχει ήδη δοθεί η άδεια στην εφαρμογή να έχει πρόσβαση στα δεδομένα του Google Calendar, για τον συγκεκριμένου χρήστη. - -Με αυτόν τον τρόπο τα ραντεβού και οι αλλαγές που θα γίνονται από τα δυο συστήματα θα συγχωνεύονται και ο χρήστης θα μπορεί να τα διαχειρίζεται και από τις δύο πλευρές. Το μόνο πρόβλημα είναι ότι από την πλευρά του Google Calendar δεν είναι δυνατό να εκκινηθεί η διαδικασία του συγχρονισμού και έτσι αυτό θα πρέπει να γίνεται πάντοτε από την πλευρά του Easy!Appointments. - -Η διαδικασία αυτή θα μπορούσε να αυτοματοποιηθεί με την χρήση της μεθόδου cron job, αλλά κάτι τέτοιο θα μπορούσε να αποφέρει επιπλέον προβλήματα, μιας και είναι απαραίτητο ο χρήστης να έχει τα κατάλληλα δικαιώματα στον server για να το κάνει και αυτό δεν είναι πάντα εφικτό. Οπότε η μέθοδος αυτή απορρίπτεται λόγο αυτής της δυσκολίας. - -Η μέθοδος συγχρονισμού του Easy!Appointments είναι αμφίδρομη. Με την έννοια αυτή εννοείται ότι συγχρονίζονται τόσο οι αλλαγές που γίνονται στο Easy!Appointments, όσο και οι αλλαγές που γίνονται από το Google Calendar, προσφέροντας έτσι μεγαλύτερη ελευθερία και προσβασιμότητα στα δεδομένα των χρηστών της εφαρμογής. Παρακάτω αναλύονται τα βήματα που ακολουθούνται κατά την διαδικασία του συγχρονισμού. - -\begin{enumerate} -\item Η διαδικασία χωρίζεται σε δύο μέρη. Το πρώτο μέρος έχει να κάνει με τον συγχρονισμό μιας ενέργειας που μόλις έχει γίνει στο Easy!Appointments (πχ ένας πελάτης πραγματοποίησε μια κράτηση στο πλάνο ενός πάροχου υπηρεσιών). Το καινούργιο αυτό ραντεβού που μόλις καταχωρήθηκε στο σύστημα θα χρειαστεί να ενσωματωθεί και στο Google Calendar. Έτσι τρέχει μια διαδικασία η οποία προσθέτει αυτό το ραντεβού στην υπηρεσία της Google. -\item Εκτός όμως του ραντεβού που δημιουργήθηκε στο Easy!Appointments, θα χρειαστεί να ληφθούν και οι αλλαγές που έχουν γίνει στο Google Calendar. Για αυτόν τον λόγο είναι απαραίτητο να ανιχνευθούν όλα τα καταχωρημένα ραντεβού και να ελεγχθούν για τυχόν αλλαγές. Επειδή αυτό όμως μπορεί να γίνει αρκετά χρονοβόρο υπάρχει μια παράμετρος στο σύστημα του Easy!Appointments η οποία καθορίζει το χρονικό διάστημα στο παρελθόν και το μέλλον για το οποίο θέλει ο χρήστης να εκτελείται ο συγχρονισμός. Επίσης τα ραντεβού που έχουν συγχρονιστεί με το Google Calendar έχουν κρατημένο το id της εγγραφής στο σύστημα της Google, έτσι ώστε να είναι δυνατό να ανιχνευθούν οι αλλαγές που έχουν γίνει από τον χρήστη. Έτσι αν για παράδειγμα ένας χρήστης διαγράψει ένα ραντεβού από το Google Calendar το οποίο ήταν συγχρονισμένο και στο Easy!Appointments, η διαδικασία του συγχρονισμού θα καταλάβει ότι το ραντεβού λείπει και έτσι θα το διαγράψει και από το σύστημα του Easy!Appointments. -\end{enumerate} \ No newline at end of file diff --git a/doc/thesis/includes/headers.tex b/doc/thesis/includes/headers.tex deleted file mode 100644 index 4989d5ef..00000000 --- a/doc/thesis/includes/headers.tex +++ /dev/null @@ -1,71 +0,0 @@ -\documentclass[oneside, 12pt]{book} - -%% ============================================================================ -%% ΟΡΙΣΜΟΣ ΤΩΝ PACKAGES ΠΟΥ ΘΑ ΧΡΗΣΙΜΟΠΟΙΗΘΟΥΝ -%% ============================================================================ -\usepackage{thesis} -\usepackage{tabularx} -\usepackage{epsfig} -\usepackage{float} -\usepackage{listings} -\usepackage{hyperref} -\usepackage{color} -\usepackage{xcolor} -\usepackage[backend=biber]{biblatex} - -%% ============================================================================ -%% ΡΥΘΜΙΣΗ ΤΩΝ HYPERLINKS -%% ============================================================================ -\hypersetup {colorlinks} -\definecolor{darkred}{rgb}{0.5,0,0} -\definecolor{darkgreen}{rgb}{0,0.5,0} -\definecolor{darkblue}{rgb}{0,0,0.5} -\hypersetup{ - colorlinks, - linkcolor=darkblue, - filecolor=darkgreen, - urlcolor=darkblue, - citecolor=darkred -} - -%% ============================================================================ -%% PHP LISTINGS STYLE -%% http://tex.stackexchange.com/a/54687 -%% http://en.wikibooks.org/wiki/LaTeX/Source_Code_Listings -%% http://en.wikibooks.org/wiki/LaTeX/Colors -%% ============================================================================ -\definecolor{dkgreen}{rgb}{0,.6,0} -\definecolor{dkblue}{rgb}{0,0,.6} -\definecolor{dkyellow}{cmyk}{0,0,.8,.3} -\definecolor{ltgrey}{RGB}{240,240,240} -\lstset{ - language = php, - basicstyle = \footnotesize\ttfamily, - keywordstyle = \color{dkblue}, - stringstyle = \color{red}, - identifierstyle = \color{dkgreen}, - commentstyle = \color{gray}, - emph =[1]{php}, - emphstyle =[1]\color{black}, - emph =[2]{if,and,or,else,public,function,try,catch,return}, - emphstyle =[2]\color{dkblue}, - numbers = left, - tabsize = 2, - backgroundcolor = \color{ltgrey}, - extendedchars = true, - showspaces = false, - showstringspaces= false} - -%% ============================================================================ -%% ΤΑ ΠΑΡΑΚΑΤΩ ΕΙΝΑΙ ΥΠΟΧΡΕΩΤΙΚΑ -%% ============================================================================ -\renewcommand{\thesistitle}{Δημιουργία διαδικτυακού συστήματος συναντήσεων (appointments) με χρήση Google Calendar PHP API} -\renewcommand{\thesisauthor}{Αλέξανδρος Τσελεγγίδης (2503)} -\renewcommand{\thesisauthorabbrv}{Α. Τσελεγγίδης} -\renewcommand{\thesisauthorinitials}{ΑΤ} -\renewcommand{\thesissupervisor}{Δρ. Νικόλαος Πεταλίδης, Επιστημονικός Συνεργάτης} -\renewcommand{\thesismonth}{Νοέμβριος} -\renewcommand{\thesisyear}{2013} - -%% ΒΙΒΛΙΟΓΡΑΦΙΑ -\addbibresource{thesis.bib} diff --git a/doc/thesis/includes/implementation.tex b/doc/thesis/includes/implementation.tex deleted file mode 100644 index 9167d01c..00000000 --- a/doc/thesis/includes/implementation.tex +++ /dev/null @@ -1,198 +0,0 @@ -%% ΣΧΕΔΙΑΣΗ & ΥΛΟΠΟΙΗΣΗ -%% Σε αυτό το κεφάλαιο περιγράφεται η διαδικασία σχεδίασης και -%% υλοποίησης της εφαρμογής. Αναλύονται οι επιλογές που έχουν -%% γίνει και με ποιόν τρόπο λειτουργούν κάποια βασικά τμήματα -%% του κώδικα. - -\chapter{Σχεδίαση \& Υλοποίηση} -Σε αυτό το κεφάλαιο γίνεται ανάλυση του συστήματος στα επιμέρους μέρη που το απαρτίζουν και περιγράφεται η διαδικασία της υλοποίησης τους. Επεξηγούνται τα σημαντικότερα σημεία στον κώδικα και οι αλγόριθμοι που χρησιμοποιούνται για την επίλυση των κυριότερων λειτουργιών. Έχουν συμπεριληφθεί τμήματα κώδικα αλλά και διαγράμματα τα οποία βοηθούν στην κατανόηση των λύσεων που επιλέχθηκαν για την ολοκλήρωση της εφαρμογής. - -%% ================================================== -%% ΑΝΑΛΥΣΗ ΔΕΔΟΜΕΝΩΝ -%% ================================================== -\section{Ανάλυση δεδομένων} -Το κυριότερο πρόβλημα που προσπαθεί να λύσει το σύστημα είναι η κράτηση και η διαχείριση ραντεβού από μια επιχείριση. Σε αυτήν την περίπτωση χρήσης έχει επικεντρωθεί η σχεδίαση και η υλοποίηση του συστήματος το οποίο περιέχει και άλλες δυνατότητες οι οποίες μπορούν όμως να θεωρηθούν λιγότερο σημαντικές. Έχοντας υπόψιν την έννοια "ραντεβού" ως την κύρια οντότητα της εφαρμογής, σχεδιάστηκε το παρακάτω μοντέλο το οποίο διευκρινίζει τις σχέσεις των οντοτήτων του συστήματος μεταξύ τους. - -\begin{figure}[ht!] -\centering -\includegraphics[width=160mm]{images/domain-model.png} -\caption{Domain model του συστήματος.} -\label{domain-model} -\end{figure} - -Με βάση αυτό το σχεδιάγραμμα μπορεί πολύ εύκολα να προκύψει και το σχεσιακό μοντέλο της βάσης δεδομένων δεδομένου ότι έχουμε τις οντότητες αλλά και τις σχέσεις μεταξύ τους. Όλοι οι χρήστες κληρονομούν την συμπεριφορά τους από μια οντότητα (User) και επιπρόσθετα κατέχουν διάφορες ιδιότητες που είναι αναγκαίες για τον ρόλο τους μέσα στην εφαρμογή. Για παράδειγμα ο χρήστης γραμματέας (Secretary) περιέχει έναν πίνακα από πάροχους (Providers) τους οποίους μπορεί να διαχειριστεί όπως και ένα ραντεβού είναι ξεκάθαρο ότι περιέχει στην πληροφορία του έναν πελάτη, έναν πάροχο και μια υπηρεσία. - -\begin{figure}[ht!] -\centering -\includegraphics[width=160mm]{images/er.png} -\caption{Σχεσιακό μοντέλο της βάσης δεδομένων (ER).} -\label{er} -\end{figure} - -Για την διαχείριση των δεδομένων της βάσης δημιουργήθηκαν ειδικές κλάσεις (models) οι οποίες περιέχουν μεθόδους που χρησιμοποιούνται από τους controllers του συστήματος. Το CodeIgniter δίνει στον προγραμματιστή ένα δικό του μέσο επικοινωνίας με την βάση δεδομένων, το οποίο είναι ένα πολύ ισχυρό και ευέλικτο εργαλείο. Η επονομαζόμενη Database Class του CodeIgniter επιτρέπει στον προγραμματιστή να εκτελεί ερωτήματα προς την βάση, να παράγει αποτελέσματα και να τα αναλύει σε ξεχωριστές εγγραφές, να κρατάει στην μνήμη ερωτήματα για γρηγορότερη ανταπόκριση (query caching) και κυριότερο την κλάση Active Record. Η κλάση αυτή έχει έναν δικό της τρόπο για την εκτέλεση των ερωτημάτων προς την βάση. Όλα τα τμήματα ενός τυπικού ερωτήματος είναι μέθοδοι οι οποίες χρησιμοποιούνται από τον προγραμματιστή ως το μέσο επικοινωνίας με την βάση δεδομένων. Το θετικό είναι ότι ανεξαρτήτως τον τύπο της βάσης η κλάση αυτή λειτουργεί με τον ίδιο τρόπο (MySQL, PostgreSQL, MSSQL κτλ). Η τεχνική αυτή λέγεται Active Record Database Pattern και έχει να κάνει με την αλλαγή adapter στην κλάση ανάλογα με τον τύπο της βάσης. Σε κάθε περίπτωση όμως ο τρόπος χρήσης της Active Record Class είναι ο ίδιος. Στο παρακάτω τμήμα κώδικα αναφέρεται ένα παράδειγμα για το πως μπορεί να βρεθεί το αναγνωριστικό μιας εγγραφής χρησιμοποιώντας ως κλειδί την διεύθυνση email. - -\lstinputlisting{snippets/find_record_id.php} - -%% ================================================== -%% ΑΡΧΙΤΕΚΤΟΝΙΚΗ ΚΩΔΙΚΑ -%% ================================================== -\section{Αρχιτεκτονική κώδικα} -Η εφαρμογή είναι γραμμένη χρησιμοποιώντας τις εξής τεχνολογίες: PHP, JavaScript, HTML, CSS, MySQL. Εκτός αυτών έχουν χρησιμοποιηθεί και κάποια βοηθητικά εργαλεία τα οποία διευκολύνουν τον προγραμματιστή στο να πετύχει καλύτερο αποτέλεσμα σε μικρότερο χρόνο. Αυτά τα εργαλεία (frameworks) όπως έχουν αναφερθεί και σε προηγούμενο κεφάλαιο είναι τα CodeIgniter (PHP), jQuery (JavaScript), Bootstrap (CSS + JavaScript). - -Όσον αφορά την αρχιτεκτονική του κώδικα έχει επιλεχθεί το μοντέλο MVC (Model - View - Controller) το οποίο υλοποιείται με άριστη απόδοση και οργάνωση χάρη στο framework CodeIgniter. Ο κώδικας PHP έχει χωριστεί σε τρία μέρη (models, views, controllers) και με αυτόν τον τρόπο παραμένει σε όλο τον κώδικα της εφαρμογής. Ο διαχωρισμός αυτός βελτιώνει τις συνθήκες συντήρησης γιατί είναι ξεκάθαρο σε ποιο από τα τρία ξεχωριστά σημεία ανήκει μια λειτουργία, όταν αυτή αναζητείται από τον προγραμματιστή. Έχουν συγγραφεί και δοκιμαστεί κλάσεις models για κάθε οντότητα οι οποίες αναλαμβάνουν την διαχείριση των δεδομένων με την βάση και παρέχουν μεθόδους που επαναχρησιμοποιούνται σε διάφορες περιπτώσεις. Επίσης έχουν δημιουργηθεί views για κάθε σελίδα που μπορεί να δει ο χρήστης τα οποία συνδέονται με ένα κομμάτι CSS κώδικα, υπεύθυνο για την μορφοποίησή τους. Τέλος τον συντονισμό αυτών των τμημάτων αναλαμβάνουν οι κλάσεις controllers οι οποίες είτε είναι υπεύθυνες για την σωστή φόρτωση μιας σελίδας της εφαρμογής, είτε απαντούν σε κλήσεις της JavaScript που γίνονται μέσω της τεχνολογίας AJAX. - -Πολύ μεγάλο μέρος της εφαρμογής έχει γραφεί σε JavaScript για να μπορέσει το περιβάλλον εργασίας του χρήστη να γίνει αρκετά φιλικό και λειτουργικό. Ο JavaScript κώδικας χωρίζεται σε διάφορες κλάσεις και namespace τα οποία χρησιμοποιούνται από μια ή και παραπάνω σελίδες και στόχο έχουν να "ζωντανέψουν" το περιεχόμενο προσθέτοντας διαδραστικότητα. Πολλές φορές είναι απαραίτητο να εκτελεστούν κλήσεις AJAX προς τον server για την λήψη πρόσθετων πληροφοριών, είτε για να αποσταλούν δεδομένα τα οποία σηματοδοτούν για παράδειγμα κάποια επεξεργασία ή και διαγραφή εγγραφής από την βάση δεδομένων. Η χρήση του AJAX κρίνεται σημαντική διότι με αυτήν αποφεύγονται οι συνεχείς επαναφορτώσεις των σελίδων, οι οποίες θα γινόταν για να μπορέσει ο client να επικοινωνήσει με τον server. Αυτό το κομμάτι αναλαμβάνεται εξ ολοκλήρου από την JavaScript και προσδίδει ευελιξία και ταχύτητα στην χρήση της εφαρμογής. Το framework jQuery αποτελεί σημαντικό εργαλείο για την διεκπεραίωση διαφόρων λειτουργιών μέσω της JavaScript διότι δίνει την δυνατότητα στον προγραμματιστή να γράψει κώδικα όμορφα δομημένο και πολύ πιο αποδοτικό από ότι θα ήταν χωρίς την χρήση του. Αυτή η ιδιότητα της βιβλιοθήκης συντελεί και στην δημοτικότητά της και την χρήση της από κολοσσούς ανάπτυξης λογισμικού. - -Για την μορφοποίηση των σελίδων της εφαρμογής χρησιμοποιήθηκε το πιο διαδεδομένο CSS framework την συγκεκριμένη την περίοδο, το Bootstap. Χρησιμοποιώντας αυτό το framework γράφτηκε νέο CSS το οποίο μορφοποιεί τις σελίδες έτσι ώστε να ανταποκρίνονται όπως πρέπει σε διάφορα μεγέθη οθονών, ενώ παράλληλα δεν χαλάει την συμβατότητα μεταξύ των διάφορων περιηγητών διαδικτύου. Το Bootstrap περιέχει και κάποια πρόσθετα JavaScript τα οποία βοηθούν σημαντικά στο οπτικό αποτέλεσμα της διεπαφής χρήστη. - -Στο παρακάτω σχεδιάγραμμα γίνεται σαφής ο διαχωρισμός του κώδικα του συστήματος στα διάφορα τμήματα που το απαρτίζουν και η χρήση των εξωτερικών εργαλείων που συντέλεσαν στην ορθή ανάπτυξη της εφαρμογής. - -\begin{figure}[ht!] -\centering -\includegraphics[width=100mm]{images/system-architecture.png} -\caption{Τα τμήματα που απαρτίζουν το Easy!Appointments.} -\label{system-architecture} -\end{figure} - -%% ================================================== -%% ΥΛΟΠΟΙΗΣΗ ΣΥΣΤΗΜΑΤΟΣ -%% ================================================== -\section{Υλοποίηση συστήματος} -Εφόσον ο αρχικός σχεδιασμός είχε ολοκληρωθεί ξεκίνησε η υλοποίηση της εφαρμογής με πρώτη εργασία τον σχεδιασμό της βάσης δεδομένων. Έχοντας ήδη σχεδιασμένο το domain model η δημιουργία του σχήματος της βάσης έγινε γρήγορα και διατηρήθηκε ως την ολοκλήρωση του έργου με μικρές προσθήκες όπου ήταν απαραίτητο. - -Στην συνέχεια, πριν γραφεί κώδικας θα έπρεπε να γίνει η επιλογή και το στήσιμο των εξωτερικών βιβλιοθηκών που θα κρίνονταν απαραίτητα για την λειτουργία του συστήματος. Σε αυτήν την φάση επιλέχθηκαν οι βασικές βιβλιοθήκες (CodeIgniter, Google API Library, jQuery, Bootstrap) καθώς και η σημαντικότερη περίπτωση χρήσης για να υλοποιηθεί πρώτη. Αυτή δεν ήταν άλλη από την κράτηση ενός ραντεβού από τον πελάτη. Αυτή η απόφαση πάρθηκε γιατί με αυτόν τον τρόπο θα καθορίζονταν εν μέρη και η αρχιτεκτονική του συστήματος καθώς αυτό θα εξελισσόταν σταδιακά με την ολοκλήρωση και των υπόλοιπων περιπτώσεων χρήσης. - -Η κύρια ροή εργασιών ως προς την υλοποίηση μιας περίπτωσης χρήσης αποτελείται από τα παρακάτω βήματα: -\begin{enumerate} -\item Συγγραφή της κλάσης model για την συγκεκριμένη οντότητα. Μερικές φορές αυτή η διαδικασία μπορεί να συμπεριλάμβανε και την δημιουργία model και για άλλες οντότητες που εμπλέκονταν στην περίπτωση χρήσης, έτσι ώστε να μπορέσει να λειτουργήσει σωστά ο κώδικας συνολικά. Οι περισσότερες κλάσεις ακολουθούν το ίδιο πρότυπο σχεδίασης και μεθόδων με μικρές διαφοροποιήσεις ανάλογα με την οντότητα που διαχειρίζονται. -\item Έλεγχος των model με δημιουργία unit tests. Μετά την ολοκλήρωση των model αυτά θα έπρεπε να δοκιμαστούν έτσι ώστε να διασφαλιστεί η σωστή λειτουργία τους. Εκτός αυτού όμως η συγγραφή unit test είναι και μια καλή ευκαιρία ως παράδειγμα της χρήσης των model από το υπόλοιπο σύστημα. Αν εντοπιζόταν κάποιο πρόβλημα κατά την εκτέλεση των test αυτό διορθωνόταν και τα test εκτελούνταν πάλι έως ότου να ολοκληρωθούν όλα με επιτυχία. -\item Εφόσον τα model ήταν ολοκληρωμένα στην συνέχεια δημιουργήθηκαν οι controllers και οι αντίστοιχες συναρτήσεις που θα ήταν υπεύθυνες για την λειτουργία του view που αντιστοιχούσε στην εκάστοτε περίπτωση χρήσης. Έτσι εκτός από τις συναρτήσεις που αναλάμβαναν να φορτώσουν μια σελίδα της εφαρμογής συγκεντρώνοντας τα δεδομένα που ήταν απαραίτητα, υλοποιήθηκαν και οι κλήσεις AJAX που ήταν απαραίτητες από την JavaScript. Αυτές οι κλήσεις συνήθως αναλάμβαναν την διεκπεραίωση κάποιας ενέργειας προς την βάση δεδομένων και επέστρεφαν πάντα κάποιο αποτέλεσμα για να μπορέσει να συνεχίσει την λειτουργία της το τμήμα της JavaScript. -\item Στην συνέχεια υλοποιούνταν το αντίστοιχο view που θα έβλεπε ο χρήστης. Σε αυτό τοποθετούνταν ο κώδικας PHP, HTML και η μορφοποίηση της σελίδας (CSS) γραφόταν στο αντίστοιχο αρχείο έτσι ώστε να παραχθεί ένα καλαίσθητο και φιλικό αποτέλεσμα. -\item Όταν το view ήταν έτοιμο θα έπρεπε να του προστεθεί και κάποια λειτουργικότητα έτσι ώστε να μπορεί να ανταποκριθεί στις ενέργειες του χρήστη. Για κάθε σελίδα χρησιμοποιούνται μια πληθώρα από βιβλιοθήκες, namespaces, κλάσεις και πρόσθετα JavaScript. Στα αντίστοιχα αρχεία τοποθετήθηκε ο κώδικας που θα ρύθμιζε την λειτουργία της σελίδας και τις ασύγχρονες κλήσεις προς τον server (AJAX). -\item Τέλος εφόσον όλα ήταν έτοιμα και η περίπτωση χρήσης είχε υλοποιηθεί χωρίς προβλήματα, όλος ο κώδικας που είχε γραφεί έπρεπε να εξεταστεί (review) για τυχόν προβλήματα λογικής και για την βελτίωση της απόδοσης του, μικραίνοντας όσο είναι δυνατόν την σύζευξη και αυξάνοντας την συνοχή. -\end{enumerate} - -Εδώ θα χρειαστεί να αναφερθεί ότι όλες οι κλήσεις AJAX που αφορούν το backend έχουν μεταφερθεί σε μια κλάση controller ξεχωριστά από τον κύριο controller του backend για να είναι καλύτερα οργανωμένες. Αν μελλοντικά ο αριθμός τους και η πολυπλοκότητα τους αυξηθεί τότε θα χρειαστεί να διαιρεθούν ξανά για να μπορέσουν να συντηρούνται πιο εύκολα. - -%% ================================================== -%% ΠΕΡΙΓΡΑΦΗ ΒΑΣΙΚΩΝ ΑΛΓΟΡΙΘΜΩΝ -%% ================================================== -\section{Περιγραφή βασικών αλγορίθμων} -Σε αυτήν την ενότητα θα γίνει ανάλυση κάποιων βασικών αλγορίθμων που αποτελούν κρίσιμα τμήματα για την λειτουργία του συστήματος. Η περιγραφή θα γίνει σχολιάζοντας τα τμήματα κώδικα που απαρτίζουν αυτούς τους αλγορίθμους αναφέροντας και τις συγκεκριμένες γραμμές στα οποία αναφέρονται. Στην επόμενη ενότητα παρέχονται κάποια σχεδιαγράμματα τα οποία μπορούν να βοηθήσουν στην κατανόηση αυτών των αλγορίθμων. - -\subsection{Πλήρης συγχρονισμός με το Google Calendar} -Η διαδικασία του πλήρη συγχρονισμού των ραντεβού με το Google Calendar αποτελεί ένας από τους κυριότερους αλγορίθμους του Easy!Appointments. Η πολυπλοκότητα της διαδικασίας συγχρονισμού δεδομένων κατέστησαν την υλοποίηση αυτού του τμήματος κώδικα αρκετά ενδιαφέρον και το αποτέλεσμα κατάφερε να καλύψει τις αρχικές απαιτήσεις. Μπορεί μελλοντικά να υπάρξουν βελτιώσεις στον κώδικα αλλά την συγκεκριμένη στιγμή ο αλγόριθμος λειτουργεί επιτυχώς και συγχρονίζει τα ραντεβού του συστήματος με τα συμβάντα που έχει περάσει ο χρήστης στο Google Calendar. - -\lstinputlisting{snippets/google_sync_algorithm.php} - -Η μέθοδος αυτή καλείται κάθε φορά που πρέπει να τρέξει ο αλγόριθμος συγχρονισμού για έναν πάροχο υπηρεσιών. Στο πρώτο μέρος του κώδικα ελέγχεται αν ο χρήστης έχει τα δικαιώματα να τρέξει αυτήν την μέθοδο και αν έχει δοθεί το αναγνωριστικό της εγγραφής του πάροχου. Έπειτα φορτώνονται τα απαραίτητα models και γίνεται η λήψη των πληροφοριών του πάροχου από την βάση (γραμμές 17 - 30). - -Για να συνεχιστεί η διαδικασία θα πρέπει να ελεγχθεί αν ο πάροχος έχει ενεργό τον συγχρονισμό με το Google Calendar. Αν η επιλογή αυτή είναι ενεργή τότε ο αλγόριθμος χρησιμοποιεί το token του πάροχου για να πιστοποιήσει την χρήση των δεδομένων του στο Google Calendar, διαφορετικά η διαδικασία τερματίζεται (γραμμές 33 - 43). - -Για να γίνει εξοικονόμηση κλήσεων προς την υπηρεσία της Google αλλά και να μειωθεί ο χρόνος διεκπεραίωσης του αλγορίθμου συγχρονισμού, το χρονικό διάστημα μέσα στο οποίο θα συγχρονισθούν τα δεδομένα περιορίζεται στο εύρος των ημερών που έχει τεθεί ως ρύθμιση για τον κάθε πάροχο (προεπιλεγμένη τιμή 5 ημέρες στο παρελθόν και 5 στο μέλλον). Αυτό είναι το χρονικό διάστημα στο οποίο θα ελεγχθούν όλα τα δεδομένα και από τα δύο συστήματα και θα συντονιστούν έτσι ώστε να είναι τα ίδια (γραμμές 47 - 54). - -Το επόμενο κομμάτι κώδικα αφού πρώτα λάβει τα ραντεβού από την βάση δεδομένων του Easy!Appointments, εξετάζει τις εγγραφές μια προς μια για το αν έχουν συγχρονιστεί με το Google Calendar. Εδώ υπάρχουν οι εξής περιπτώσεις: -\begin{enumerate} -\item Το ραντεβού δεν έχει ακόμα συγχρονιστεί οπότε θα πρέπει να προστεθεί στο Google Calendar (γραμμές 88 - 93). -\item Το ραντεβού είναι συγχρονισμένο και πρέπει να ελεγχθεί αν υπάρχουν διαφορές με το συμβάν που είναι καταχωρημένο στο Google Calendar. Αν ναι τότε αυτό σημαίνει ότι ο χρήστης έχει αλλάξει τα στοιχεία του συμβάντος στο Google Calendar και η εγγραφή του ραντεβού στο Easy!Appointments θα πρέπει να ενημερωθεί (γραμμές 97 - 126). -\item Το ραντεβού είναι συγχρονισμένο αλλά δεν έχει βρεθεί στο Google Calendar. Εφόσον δεν έχει βρεθεί η εγγραφή σημαίνει ότι ο χρήστης την έχει διαγράψει από το Google Calendar και έτσι θα πρέπει να διαγραφεί και από το Easy!Appointments (γραμμές 130 - 131). -\end{enumerate} -Με το πέρας αυτού του τμήματος κώδικα όλα τα ραντεβού του Easy!Appointments θα πρέπει να έχουν συγχρονιστεί με το Google Calendar. - -Τα μη διαθέσιμα διαστήματα χρησιμοποιούνται ως ραντεβού στον συγκεκριμένο αλγόριθμο με την διαφορά ότι δεν υπάρχουν σε αυτά πληοροφίες για κάποιο πελάτη ή υπηρεσία (γραμμές 83 - 84). - -Υπάρχουν όμως συμβάντα στην υπηρεσία της Google τα οποία μπορεί να έχουν προστεθεί απευθείας στο Google Calendar και να μην υπάρχουν στο Easy!Appointments. Σε αυτήν την περίπτωση θα πρέπει να ανιχνευθούν και να εξεταστούν όλα τα συμβάντα που αντιστοιχούν στην χρονική περίοδο συγχρονισμού (5 ημέρες πριν και 5 ημέρες μετά την τρέχουσα ημερομηνία) και να ελεγχθεί αν υπάρχει κάποιο συμβάν που δεν είναι συγχρονισμένο. - -Αυτήν την εργασία αναλαμβάνει το επόμενο κομμάτι κώδικα το οποίο χρησιμοποιώντας την βιβλιοθήκη Google API μπορεί να διαβάσει τα συμβάντα τα οποία βρίσκονται στο Google Calendar. Η διαδικασία ξεκινάει με την λήψη αυτών των συμβάντων τα οποία στην συνέχεια εξετάζονται ένα προς ένα για το αν υπάρχουν στο Easy!Appointments. Αν όχι τότε προστίθενται και συγχρονίζονται και στα δύο συστήματα και έτσι διασφαλίζεται η ακεραιότητα των δεδομένων και στα δύο συστήματα (γραμμές 137 - 159). - -Τέλος η συνάρτηση επιστρέφει την σταθερά AJAX\_SUCCESS την οποία θα διαβάσει η JavaScript και έτσι θα γνωρίζει ότι η διαδικασία έχει ολοκληρωθεί με επιτυχία. Διαφορετικά αν προκύψουν σφάλματα αυτά επιστρέφονται σε JSON μορφή και εμφανίζονται με ένα φιλικό μήνυμα προς τον χρήστη. - -\subsection{Υπολογισμός διαθέσιμων ωρών πάροχου} -Ένα κομβικό σημείο στον κώδικα της εφαρμογής είναι ο υπολογισμός των διαθέσιμων ωρών ενός πάρoχου στις οποίες μπορεί ένας πελάτης να κλείσει ένα ραντεβού για μια υπηρεσία, χωρίς να υπάρχει σύγκρουση με άλλα συμβάντα. Για να επιτευχθεί ο υπολογισμός αυτός χρειάζεται να γίνουν αρκετοί έλεγχοι έτσι ώστε τα αποτελέσματα να είναι σωστά και να μην δημιουργούνται προβλήματα με τα πλάνα των πάροχων υπηρεσιών. Η διαδικασία χωρίζεται σε δύο μεθόδους με την πρώτη να υπολογίζει τα ελεύθερα χρονικά διαστήματα του πάροχου και την δεύτερη να υπολογίζει τις ακριβείς ώρες στις οποίες θα μπορεί ο πελάτης να κλείσει ραντεβού. - -\lstinputlisting{snippets/provider_available_periods.php} - -Το πρώτο πράγμα που πρέπει να γίνει είναι η λήψη του πλάνου εργασίας του πάροχου καθώς και των ήδη καταχωρημένων ραντεβού για την επιλεγμένη ημερομηνία. Επίσης υπάρχει και η περίπτωση να πρέπει να αποκλειστούν κάποια ραντεβού κατά τον υπολογισμό των διαθέσιμων ωρών οπότε αν έχουν οριστεί τέτοιες εγγραφές δεν λαμβάνονται υπόψιν στον υπολογισμό. Αυτή η επιλογή είναι απαραίτητη όταν χρειάζεται ο πελάτης να επεξεργαστεί ένα ήδη καταχωρημένο ραντεβού το οποίο δεν θα πρέπει να εμφανίζει ως δεσμευμένη την ώρα που καταλαμβάνει το ίδιο στο ημερολόγιο του πάροχου. Τα στοιχεία αυτά θα χρησιμοποιηθούν έτσι ώστε τα διαθέσιμα διαστήματα που θα υπολογιστούν να αντιπροσωπεύουν τον χρόνο στον οποίο ο πάροχος θα είναι διαθέσιμος (γραμμές 23 - 47). - -Έπειτα θα διαχωριστούν τα ελεύθερα χρονικά διαστήματα του πάροχου από τα διαλείμματα και τα ήδη καταχωρημένα ραντεβού. Αρχικά για την επιλεγμένη ημέρα του ραντεβού ελέγχονται αν υπάρχουν καθόλου διαλείμματα. Αν ναι, τότε τα διαθέσιμα διαστήματα χωρίζονται μεταξύ των διαλειμμάτων του πάροχου (γραμμές 54 - 81) και παράγονται νέα χρονικά διαστήματα. Στην συνέχεια λαμβάνονται υπόψιν τα ραντεβού που έχουν ήδη κρατηθεί. Τα διαθέσιμα χρονικά διαστήματα του πάροχου θα διασπαστούν ξανά μεταξύ των ραντεβού αυτών και έτσι θα ολοκληρωθεί η διαδικασία του υπολογισμού (γραμμές 84 - 137). Αν την επιλεγμένη ημερομηνία ο πάροχος δεν έχει κανένα ραντεβού τότε δεν πραγματοποιείται καμία επιπλέον διάσπαση και το αποτέλεσμα επιστρέφεται όπως είναι. Στην επόμενη μέθοδο ο πίνακας που περιέχει τα διαστήματα θα χρησιμοποιηθεί για να υπολογιστούν οι ακριβείς διαθέσιμες ώρες στις οποίες θα μπορεί ο πελάτης να κλείσει κάποιο ραντεβού για την επιλεγμένη υπηρεσία. - -\lstinputlisting{snippets/provider_appointment_hours.php} - -Η δεύτερη μέθοδος αποτελεί απάντηση σε κλήση της JavaScript με χρήση της τεχνικής AJAX. Όταν ο client καλεί αυτήν την μέθοδο παρέχει τα στοιχεία του πάροχου, την διάρκεια της επιλεγμένης υπηρεσίας (σε λεπτά) και το αν ο χρήστης επεξεργάζεται το συγκεκριμένο ραντεβού ή όχι (παράμετρος manage\_mode). Αυτό που εκτελείται αρχικά είναι η λήψη των ελεύθερων χρονικών διαστημάτων του πάροχου χρησιμοποιώντας την προαναφερθέντα μέθοδο get\_provider\_available\_time\_periods (γραμμές 28 - 34). - -Έπειτα θα υπολογιστούν οι διαθέσιμες ώρες στις οποίες θα μπορέσει ο πελάτης να κλείσει ραντεβού. Αυθαίρετα και για λόγους ευχρηστίας έχει τεθεί το χρονικό διάστημα μεταξύ των ελεύθερων ωρών να είναι τα 15 λεπτά. Αυτό που κάνει το συγκεκριμένο κομμάτι κώδικα είναι ουσιαστικά ο διαχωρισμός των ελεύθερων χρονικών διαστημάτων του πάροχου σε ώρες τις οποίες χωρίζουν 15 λεπτά τουλάχιστον και οι οποίες μπορούν να χωρέσουν την διάρκεια της υπηρεσίας για την οποία ενδιαφέρεται ο πελάτης, πριν την λήξη του διαθέσιμου χρονικού διαστήματος (γραμμές 41 - 74). - -Στο τελευταίο μέρος αυτής της μεθόδου ελέγχεται αν η επιλεγμένη ημερομηνία αντιστοιχεί στην σημερινή και αν αυτό ισχύει αφαιρούνται οι παρελθοντικές διαθέσιμες ώρες έτσι ώστε να μην μπορεί ο πελάτης να κλείσει ραντεβού σε μια παρελθοντική χρονική στιγμή. Το σύστημα στο frontend δεν επιτρέπει ούτως ή άλλος την επιλογή παρελθοντικής ημερομηνίας, αλλά απαιτείται στην συγκεκριμένη περίπτωση να ελεγχθούν οι παρελθοντικές ώρες του ραντεβού. Επίσης είναι σημαντικό να αναφερθεί ότι η εφαρμογή παρέχει μια παράμετρο η οποία ορίζει το χρονικό διάστημα που θα πρέπει να χωρίζει ένα ραντεβού από την ώρα που αυτό γίνεται κράτηση ή επεξεργάζεται. Ο λόγος γίνεται για την ρύθμιση του συστήματος με το όνομα "book\_advance\_timeout" η οποία μετράται σε λεπτά και λαμβάνεται υπόψιν στον υπολογισμό των διαθέσιμων ωρών. - -%% ================================================== -%% ΔΙΑΓΡΑΜΜΑΤΑ ΚΩΔΙΚΑ -%% ================================================== -\section{Διαγράμματα Κώδικα} -Σε αυτήν την ενότητα θα παρατεθούν κάποια διαγράμματα κώδικα τα οποία θα βοηθήσουν τον αναγνώστη στην κατανόηση της λειτουργίας του συστήματος και στον τρόπο με τον οποίο διεκπεραιώνονται οι εργασίες που απαιτούνται στην εκάστοτε περίπτωση χρήσης. Τα διαγράμματα αυτά ακολουθούν το σχεδιαστικό πρότυπο UML το οποίο αποτελεί την πιο δημοφιλής γλώσσα μοντελοποίησης εδώ και αρκετά χρόνια. - -Η εφαρμογή που χρησιμοποιήθηκε για τον σχεδιασμό των διαγραμμάτων αυτών είναι η draw.io και πρόκειται για μια διαδικτυακή πλατφόρμα με την οποία μπορούν να γίνουν σχεδιαγράμματα πολλών διαφορετικών τύπων. Το draw.io είναι δωρεάν προς χρήση και μπορεί να βρεθεί στην διεύθυνση http://www.draw.io. - -\subsection{Διαγράμματα ροής} -Τα διαγράμματα ροής δείχνουν τον τρόπο και την σειρά με την οποία λειτουργούν οι διεργασίες και τα αντικείμενα μεταξύ τους για την διεκπεραίωση ενός σκοπού. Σε αυτά είναι εύκολο να διακριθούν ποιοι ηθοποιοί, αντικείμενα, διεπαφές και μέθοδοι αλληλεπιδρούν έτσι ώστε τα δεδομένα που χρειάζονται για την εργασία να παραχθούν επιτυχώς και να φτάσουν ακέραια στον προορισμό τους. Σε αυτά τα διαγράμματα ο χρονικός προσδιορισμός της κάθε αλληλεπίδρασης είναι εμφανής και πολύ σημαντικός για να μπορέσει ο προγραμματιστής να καταλάβει με ποια σειρά θα πρέπει να πορευτεί η εκτέλεση έτσι ώστε αυτός να καταλήξει σε αναμενόμενο αποτέλεσμα. Συνήθως τα διαγράμματα ροής συγχέονται με το σενάριο κάποιας περίπτωσης χρήσης αλλά μπορούν να διασπαστούν και σε μικρότερα τμήματα τα οποία να επικεντρώνουν στα σημεία που είναι πιο σημαντικά. - -\begin{figure}%% [Η] αυτή η εντολή θα τοποθετήσει το διάγραμμα ακριβώς σε αυτό το σημείο. Το latex όμως πάντα προσπαθεί να αφήσει όσο λιγότερα κενό χόρο γίνεται και έτσι τα διαγράμματα δεν θα εμφανιστούν με την σειρά που γράφονται στον κώδικα. -\centering -\includegraphics[width=150mm]{images/sd-save-appointment.png} -\caption{Διάγραμμα ροής για την διαδικασία αποθήκευσης ενός ραντεβού.} -\label{sd-save-appointment} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width=150mm]{images/sd-sync-appointment.png} -\caption{Διάγραμμα ροής για την διαδικασία προσθήκης ενός ραντεβού στο Google Calendar.} -\label{sd-save-appointment} -\end{figure} - -\subsection{Διαγράμματα δραστηριότητας} -Τα διαγράμματα δραστηριότητας αποτελούν γραφικές παρουσιάσεις της δραστηριότητας του που ακολουθεί το σύστημα ανάλογα με τις αποφάσεις που λαμβάνονται μέσα από τον κώδικα. Σε αυτά τα διαγράμματα μπορούν να φανούν τα σημεία στα οποία υπάρχουν βρόγχοι επανάληψης, τα σημεία όπου παίρνονται αποφάσεις όπως και επίσης τις διαδικασίες που τρέχουν ταυτόχρονα και σε ποιο σημείο χρονικά γίνεται αυτό. Κατά κύριο λόγο τα διαγράμματα δραστηριότητας δείχνει την συνολική ροή του ελέγχου μέσα από την εκτέλεση μιας συγκεκριμένης διαδικασίας. - -\begin{figure} -\centering -\includegraphics[width=90mm]{images/ad-book-appointment.png} -\caption{Διάγραμμα δραστηριότητας της διαδικασίας κράτησης ραντεβού.} -\label{ad-book-appointment} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width=70mm]{images/ad-install-application.png} -\caption{Διάγραμμα δραστηριότητας της διαδικασίας εγκατάστασης της εφαρμογής.} -\label{ad-install-application} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width=70mm]{images/ad-sync-appointments.png} -\caption{Διάγραμμα δραστηριότητας της διαδικασίας αμφίδρομου συγχρονισμού με το Google Calendar.} -\label{ad-sync-appointments} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width=70mm]{images/ad-provider-available-hours.png} -\caption{Διάγραμμα δραστηριότητας του υπολογισμού των διαθέσιμων ωρών ενός πάροχου.} -\label{ad-provider-available-hours} -\end{figure} - -\subsection{Διαγράμματα κλάσεων} -Στην τεχνολογία λογισμικού, τα διαγράμματα κλάσεων περιγράφουν την στατική δομή ενός συστήματος δείχνοντας τις κλάσεις, τις ιδιότητες, τις λειτουργίες και τις σχέσεις μεταξύ των αντικειμένων. Τα σχεδιαγράμματα αυτά είναι τα βασικότερα για έναν προγραμματιστή διότι μπορεί άμεσα να πληροφορηθεί σχετικά με την δομή του κώδικα και με ποιόν τρόπο θα πρέπει να συνεχιστεί η διαδικασία της υλοποίησης. Επίσης είναι εμφανές και οι αρχιτεκτονικές επιλογές που έχουν γίνει καθώς κάθε σχεδιαστικό πρότυπο που πρέπει να έχει ο κώδικας μπορεί να διακριθεί και να περιγραφή σε αυτά τα διαγράμματα. Καλή πρακτική είναι πάντα ένα διάγραμμα να περιέχει μόνο την ουσία οπότε στο υποκεφάλαιο αυτό εμφανίζονται διαγράμματα κλάσης τα οποία δείχνουν κάποιες σχεδιαστικές επιλογές που έχουν γίνει στην εφαρμογή. - -\begin{figure} -\centering -\includegraphics[width=150mm]{images/cd-backend-users.png} -\caption{Διάγραμμα κλάσεων της δομής JavaScript στην σελίδα διαχείρισης των χρηστών.} -\label{cd-backend-users} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width=150mm]{images/cd-backend-settings.png} -\caption{Διάγραμμα κλάσεων της δομής JavaScript στην σελίδα ρυθμίσεων της εφαρμογής.} -\label{cd-backend-settings} -\end{figure} diff --git a/doc/thesis/includes/introduction.tex b/doc/thesis/includes/introduction.tex deleted file mode 100644 index c2c0831f..00000000 --- a/doc/thesis/includes/introduction.tex +++ /dev/null @@ -1,144 +0,0 @@ -%% ΕΙΣΑΓΩΓΙΚΟ ΚΕΦΑΛΑΙΟ -%% Το μέρος του εγγράφου αυτού περιέχει τα πρώτα μέρη της διπλωματικής -%% (πρωτοσέλιδο, περιεχόμενα, πρόλογος κτλ) καθώς και ένα κεφάλαιο που -%% αναλύει και περιγράφει το πρόβλημα που επιλύει το σύστημα που αναπτήχθηκε. - -\Titlepage -\Declarationpage - -\begin{Abstract} -Η εργασία αυτή πραγματεύεται την υλοποίηση ενός διαδικτυακού συστήματος κρατήσεων ραντεβού για επιχειρήσεις με πλήρη περιβάλλον διαχείρισης και την δυνατότητα συγχρονισμού των ραντεβού με το Google Calendar API. Στόχος είναι να κατασκευαστεί ένα ευέλικτο σύστημα το οποίο να είναι σε θέση να εξυπηρετήσει τις ανάγκες οποιασδήποτε επιχείρησης βελτιώνοντας έτσι την μηχανογράφηση, την οργάνωση και κατ' επέκταση την απόδοση της. Όλα αυτά σαφώς συντελούν στην μείωση του κόστους λειτουργίας, κάτι το οποίο είναι πολύ σημαντικό. Για την υλοποίηση της εφαρμογής επιλέχθηκε η γλώσσα προγραμματισμού PHP και JavaScript καθώς και κάποιες εξωτερικές βιβλιοθήκες κώδικα, οι οποίες φάνηκαν πολύ χρήσιμες. -\end{Abstract} - -\tableofcontents -\listoffigures - -\begin{Definitions} -Στο έγγραφο αυτό υπάρχουν κάποιες έννοιες οι οποίες χρησιμοποιούνται -σε διάφορα σημεία. Παρακάτω παρατίθενται οι περιγραφές τους. -\begin{description} -\item [Easy!Appointments] Με την ονομασία Easy!Appointments θα γίνεται αναφορά στο σύστημα που υλοποιήθηκε. - -\item [Διαχειριστής] Ο διαχειριστής του συστήματος είναι ο χρήστης ο οποίος έχει όλα τα δικαιώματα αλλαγών και ρυθμίσεων του Easy!Appointments. Μπορεί να ορίσει νέες υπηρεσίες και πάροχους υπηρεσίας, να ρυθμίσει το σύστημα ειδοποιήσεων και να εκτελέσει όλες τις δυνατές διαδικασίες διαχείρισης των δεδομένων. - -\item [Πάροχος Υπηρεσίας] Ο πάροχος υπηρεσίας είναι η οντότητα που εξυπηρετεί μια ή περισσότερες υπηρεσίες. Μπορεί να αντιπροσωπεύει ένα άτομο ή μια ομάδα ατόμων. Σε κάθε περίπτωση όμως διαχειρίζεται από έναν χρήστη του συστήματος. - -\item [Πελάτης] Ο πελάτης αφού δει τις διαθέσιμες ημερομηνίες και ώρες για τις επιλεγμένες υπηρεσίες και παρόχους, μπορεί να κλείνει ραντεβού με την επιχείρηση. Αν γίνει οποιαδήποτε αλλαγή σε κάποιο ραντεβού του πελάτη τότε αυτός θα ενημερωθεί με σχετικό email. - -\item [Γραμματέας] Ο γραμματέας είναι ένας χρήστης ο οποίος μπορεί να διαχειριστεί τα ραντεβού και τους πελάτες του συστήματος για συγκεκριμένους πάροχους υπηρεσιών. Το σε ποιους πάροχους αντιστοιχεί ο κάθε χρήστης γραμματέας ορίζεται από τον διαχειριστή στο περιβάλλον ρυθμίσεων της εφαρμογής. - -\item [Πλάνο Πάροχου] Από την στιγμή που κλείνονται ραντεβού σε έναν πάροχο υπηρεσιών το ημερολογιακό του πλάνο αρχίζει να γεμίζει από χρονικά διαστήματα, τα οποία είναι δεσμευμένα και αντιπροσωπεύουν συναντήσεις με τους πελάτες. Εκτός αυτού υπάρχει και η δυνατότητα να τεθεί ένα ανενεργό χρονικό διάστημα, στο οποίο ο συγκεκριμένος πάροχος δεν θα είναι διαθέσιμος έτσι ώστε να μην μπορούν οι πελάτες να κλείνουν ραντεβού σε αυτό το διάστημα. Αυτό το πλάνο μπορεί να συγχρονιστεί με το Google Calendar έτσι ώστε να είναι προσβάσιμο και από άλλες υπηρεσίες. - -\end{description} -\end{Definitions} - -%% ============================================= -%% ΚΕΦΑΛΑΙΟ 1 - ΕΙΣΑΓΩΓΗ -%% ============================================= -\chapter{Εισαγωγή} -\leftmark\rightmark -Το παρόν κεφάλαιο επεξηγεί τον σκοπό ανάπτυξης του Easy!Appointments καθώς και τις ανάγκες που καλύπτει σε μια επιχείρηση. Επιπρόσθετα αναφέρονται παρόμοια συστήματα και οι διαφορές που έχουν σε σχέση με την εφαρμογή που υλοποιήθηκε. - -\section {Ποια προβλήματα προσπαθεί να λύσει η εφαρμογή} -Οι επιχειρήσεις από την φύση τους χρειάζεται να έρχονται σε επαφή με τους πελάτες για να μπορέσουν να τους εξυπηρετήσουν και έτσι να λάβουν την αμοιβή τους. Ανάλογα με την μορφή και το είδος της επιχείρησης η επαφή αυτή διαφέρει. Για παράδειγμα κάποιες επιχειρήσεις έρχονται σε επαφή με περισσότερους πελάτες, άλλες με λιγότερους αλλά η εξυπηρέτηση είναι παθητική (πχ κατάστημα ηλεκτρονικών ειδών) και κάποιες απαιτούν ιδιαίτερη προσοχή στον πελάτη καθώς η εξυπηρέτησή του μπορεί να γίνει μόνο προσωπικώς, από κάποιον υπάλληλο ή επαγγελματία (πάροχος της υπηρεσίας). Η τελευταία κατηγορία περιέχει ένα μεγάλο εύρος επιχειρήσεων το οποίο για να οργανώσει και να διευκολύνει το πελατειακό κοινό του λειτουργεί κανονίζοντας ραντεβού με τους ενδιαφερόμενους πελάτες. - -Η κράτηση ενός ραντεβού είναι μια διαδικασία η οποία γίνεται συνήθως τηλεφωνικώς, είτε μετά από προσωπικό κανονισμό με κάποιον αρμόδιο. Η διαδικασία αυτή αποτελείται τις περισσότερες φορές από τα παρακάτω μέρη: -\begin{enumerate} -\item Ο ενδιαφερόμενος πελάτης έρχεται σε επαφή με την επιχείρηση και ζητάει να κάνει κράτηση την επιθυμητή ημερομηνία και ώρα, για μια συγκεκριμένη υπηρεσία. -\item Ο αρμόδιος υπάλληλος ψάχνει σε κάποιο ημερολόγιο ή αρχείο υπολογιστή τα ραντεβού για την συγκεκριμένη ημερομηνία και ανάλογα με την διαθεσιμότητα ανταποκρίνεται στον πελάτη. -\item Αν η συγκεκριμένη χρονική στιγμή δεν είναι διαθέσιμη θα χρειαστεί να γίνει μια αντιπρόταση από τον υπάλληλο ή ο πελάτης να βρει κάποια άλλη στιγμή που θα είναι αυτός διαθέσιμος. -\end{enumerate} -Αν παρατηρήσουμε όμως την παραπάνω διαδικασία, θα δούμε πως έχει κάποια σημαντικά μειονεκτήματα, τα οποία μάλιστα συνεπάγονται την αύξηση του κόστους λειτουργίας μιας επιχείρησης και την μείωση της ποιότητας εξυπηρέτησης των πελατών. - -Η ίδια η διαδικασία της κράτησης ενός ραντεβού με τον συγκεκριμένο τρόπο απαιτεί από μόνη της την ύπαρξη ενός υπαλλήλου, ο οποίος θα αφιερώνει αρκετό, αν όχι τον περισσότερο από τον χρόνο του για να κάνει αυτήν την εργασία. Αυτό πρακτικά σημαίνει δέσμευση ανθρώπινων πόρων της επιχείρησης και συνεπάγεται στην αύξηση των εξόδων λειτουργίας. - -Επιπλέον η ίδια η διαδικασία μπορεί να είναι χρονοβόρα και κουραστική για τους πελάτες, ειδικά στις περιπτώσεις όπου υπάρχει λίγο προσωπικό για να καλύψει μεγάλο κοινό (πχ νοσοκομεία). Στις περιπτώσεις αυτές οι πελάτες περιμένουν στην αναμονή για μεγάλο χρονικό διάστημα και μάλιστα πολλές φορές δεν πιάνουν γραμμή για να μπορέσουν να κρατήσουν κάποιο ραντεβού. Επίσης πρέπει να σημειωθεί ότι όταν ο πελάτης καταφέρει να κλείσει το ραντεβού του συνήθως δεν έχει επιλογή για το πότε θα γίνει και απλώς ενημερώνεται για την ημερομηνία την οποία έχει ορίσει το προσωπικό, ανάλογα με τις εκάστοτε συνθήκες. - -Εκτός αυτών η εκτέλεση αυτής της διαδικασίας είναι αρκετά επιρρεπής στο να έχει ασαφές αποτελέσματα με την έννοια του ότι δεν υπάρχει κάποιο κοινό σημείο αναφοράς για την συμφωνία που πραγματοποιείται μεταξύ της επιχείρησης και του πελάτη, έτσι ώστε να μπορεί να γίνει εξακρίβωση και επαλήθευση των ιδιοτήτων μιας κράτησης και από τις δύο πλευρές. Αυτό μπορεί να οδηγήσει σε προβλήματα με τους πελάτες, κάτι το οποίο δεν είναι επιθυμητό σε καμία περίπτωση. - -Μικρό είναι το μέρος των πληροφοριών που καταγράφεται με το πέρας της κράτησης, καθώς τα μέσα που χρησιμοποιούνται δεν επιτρέπουν ή κάνουν δύσκολη και χρονοβόρα την αποθήκευση όλων των δεδομένων. Αυτό συντελεί στην πρόσθετη μείωση της ποιότητας εξυπηρέτησης και της απόδοσης της επιχείρησης. - -Τα δεδομένα αυτά διαχειρίζονται συνήθως δύσκολα. Ακόμα και στην περίπτωση που χρησιμοποιούνται ηλεκτρονικά μέσα για την αποθήκευση των κρατήσεων η τροποποίηση ή ο έλεγχος μπορούν να είναι δύσκολες και χρονοβόρες διαδικασίες, οι οποίες εξαρτώνται κάθε φορά από το επίπεδο της οργάνωσης της επιχείρησης και τις τεχνολογίες που χρησιμοποιούνται. - -Επίσης τα δεδομένα αυτά δεν είναι προσβάσιμα από οποιονδήποτε ανά πάσα στιγμή, αλλά μόνο στον χώρο της επιχείρησης και μόνο από το άτομο το οποίο διαχειρίζεται τα ραντεβού. - -Τα παραπάνω προβλήματα διογκώνονται σημαντικά όταν πρόκειται για μεγάλες επιχειρήσεις και οργανισμούς οι οποίοι εξυπηρετούν μεγάλο αριθμό πελατών. - -\section {Γιατί είναι σημαντικά τα προβλήματα αυτά} -Οι απαιτήσεις και η ανταγωνιστικότητα που υπάρχει μεταξύ των επιχειρήσεων αυτήν την εποχή απαιτεί την γρήγορη και άμεση διεκπεραίωση διεργασιών και την όσο το δυνατόν καλύτερη οργάνωση τους, για να μπορούν να παρέχουν υπηρεσίες υψηλού επιπέδου με το χαμηλότερο δυνατό κόστος και προσωπικό. Για να επιτύχουν τον σκοπό αυτό οι επιχειρήσεις πρέπει να επιλέξουν τα κατάλληλα εργαλεία οργάνωσης και εξυπηρέτησης των πελατών τους. - -Βλέποντας τα προβλήματα που αναφέρθηκαν προηγουμένως είναι κατανοητό ότι με την χρήση της έως τώρα μεθόδου κράτησης ραντεβού επέρχεται μείωση της ποιότητας και της απόδοσης της επιχείρησης. Αυτό σημαίνει ότι το επίπεδο εξυπηρέτησης είναι χαμηλότερο και έτσι η επιχείρηση αδυνατεί να είναι ανταγωνιστική προς τις άλλες καθώς γίνεται σπατάλη πόρων για την υλοποίηση αυτής της διαδικασίας. - -Η μείωση αυτή επιφέρει αύξηση του κόστους λειτουργίας το οποίο αποτελεί ένα επιπρόσθετο εμπόδιο στην προσπάθεια για ανάπτυξη και επέκταση. Πολλές φορές μάλιστα αυτή η αύξηση του κόστους σε συνδυασμό με άλλους παράγοντες μπορεί να συντελέσουν στην μη βιωσιμότητα και το κλείσιμο της επιχείρησης, εφόσον αυτή δεν μπορεί να παράγει κέρδη. - -Παρατηρείται λοιπόν ότι η σημερινή οργάνωση των επιχειρήσεων που λειτουργούν με ραντεβού θα μπορούσε να βελτιωθεί με την χρήση ενός ηλεκτρονικού συστήματος που θα επίλυε τα προαναφερθέντα προβλήματα και θα πρόσδιδε μεγαλύτερη ευκολία στην εξυπηρέτηση του κοινού. Η προτεινόμενη λύση αποσκοπεί στο να εκπληρώσει αυτά τα κενά και να εντάξει στο ενεργητικό της επιχείρησης ένα δυνατό εργαλείο οργάνωσης. - -\section{Παρόμοιες λύσεις που υπάρχουν ήδη} -Όπως είναι φυσικό για ένα τέτοιο μείζων ζήτημα υπάρχουν ήδη αρκετές εφαρμογές που αναλαμβάνουν την μηχανογράφηση των ραντεβού μιας επιχείρησης. Όλες οι εφαρμογές είναι διαδικτυακές και σε μερικές περιπτώσεις συναντάται η διάθεση τους και για κινητές συσκευές. Οι εταιρείες κάνουν προσπάθειες στο να καταστήσουν τα λογισμικά τους εύκολα στην χρήση παρέχοντας αρκετές λειτουργίες επικοινωνίας με άλλα δημοφιλή συστήματα όπως για παράδειγμα το Outlook, το iCal και το Google Calendar. Παρακάτω περιγράφονται κάποια από αυτά τα συστήματα. - -\subsection{Genbook} -Το Genbook είναι μια online υπηρεσία που προσφέρει στις επιχειρήσεις την δυνατότητα να εγγραφούν (πληρώνοντας το αντίτιμο) και να χρησιμοποιήσουν την εφαρμογή που τους επιτρέπει να διαχειρίζονται τα ραντεβού. Παρέχει αρκετά φιλικό περιβάλλον, είναι παραμετροποιήσιμο και περιέχει την δυνατότητα παραγωγής στατιστικών στοιχείων για τις υπηρεσίες που είναι διαθέσιμες προς το κοινό. - -Αυτό που δεν υποστηρίζει είναι η δημιουργία πολλαπλών πλάνων που να αντιπροσωπεύουν διαφορετικούς τομείς ή υπαλλήλους (όλα τα ραντεβού φαίνονται σε ένα ημερολόγιο). - -Παρατηρήσεις: επί πληρωμή, ικανοποιητικά παραμετροποιήσιμο, δημιουργία στατιστικών - -\href{http://www.genbook.com}{www.genbook.com} - -\subsection{Web Appointment Scheduling System (Open Source)} -Το WASS είναι μια λύση ανοιχτού κώδικα η οποία περιέχει τις βασικότερες λειτουργίες διαχείρισης ραντεβού για μια επιχείρηση. Από την εφαρμογή αυτή λείπουν κάποια στοιχεία διαχείρισης και παραμετροποίησης και το γραφικό περιβάλλον του χρήστη χρειάζεται επιπλέον δουλειά. Παρ' όλα αυτά είναι δωρεάν και προτείνεται για οποιαδήποτε μικρή επιχείρηση. Η εφαρμογή υποστηρίζει το iCal της Apple και την δημιουργία πολλών πλάνων. - -Παρατηρήσεις: δωρεάν, βασικές λειτουργίες, ανοιχτός κώδικας, υποστήριξη iCal - -\href{https://wass.princeton.edu/pages/login.page.php}{www.wass.princeton.edu} | -\href{http://sourceforge.net/projects/wass/}{www.sourceforge.net} - -\subsection{Appointment-Plus} -Το Appointment-plus είναι από τις πιο οργανωμένες και εμπλουτισμένες εφαρμογές που υπάρχουν σε αυτόν τον τομέα. Έχει εκδόσεις για οποιαδήποτε συσκευή (pc, tablets, smartphones), όμορφο περιβάλλον, υποστήριξη συγχρονισμού δεδομένων με άλλες υπηρεσίες και εφαρμογές (Google, Outlook, iCal κτλ), χρήση από πολλούς υπαλλήλους και πολλά πλάνα. Παρέχει λειτουργία αναμονής για τους πελάτες σε περίπτωση που η επιθυμητή ώρα είναι πιασμένη. Υπάρχει σύστημα email στο οποίο ο πελάτης μπορεί να κάνει επιλογές και να τις αποστείλει πίσω στο σύστημα. Δυνατότητα για τροποποίηση της σελίδας που βλέπει ο χρήστης και πώλησης προϊόντων μέσω της εφαρμογής. Η εταιρεία προσφέρει σε κάθε πελάτη έναν βοηθό στον οποίο θα μπορεί να απευθυνθεί για να ρυθμίσει την εφαρμογή. - -Παρατηρήσεις: επί πληρωμή, πλήρως παραμετροποιήσιμο, λειτουργία σε διαφορετικές συσκευές, πολλαπλά πλάνα, υποστήριξη (τηλέφωνο - email), το χρησιμοποιούν μεγάλες εταιρείες, οργανισμοί και πανεπιστημιακά ιδρύματα - -\href{http://www.appointment-plus.com/}{www.appointment-plus.com} - -\subsection{Acuity Scheduling} -Η εφαρμογή αυτή αν και πιο απλή από την Appointment-plus περιέχει όλες τις βασικές λειτουργίες που θα χρειαστεί μια επιχείρηση για την υλοποίηση ενός συστήματος ραντεβού. Υποστηρίζει την δυνατότητα τροποποίησης της εμφάνισης, δημιουργία πολλών υπαλλήλων και πλάνων, ηλεκτρονικών πληρωμών με πιστωτική κάρτα, εξαγωγή ημερολογίου σε άλλες εφαρμογές (Facebook, Google και Outlook), ιστορικό, διαχείριση πελατών και λειτουργία σε iPhone. Επίσης δίνει την δυνατότητα πώλησης προϊόντων (eshop) για ηλεκτρονικές αγορές. - -Παρατηρήσεις: επί πληρωμή (δωρεάν για έναν χρήστη αλλά με περιορισμούς), υποστήριξη προϊόντων, iPhone, εξαγωγή σε Google, Outlook και Facebook - -\href{http://www.acuityscheduling.com/}{www.acuityscheduling.com} - -\subsection{SetMore} -Το SetMore έχει απλή και όμορφη εμφάνιση και παρέχει ένα πλήρως παραμετροποιήσιμο περιβάλλον. Είναι το μόνο που υποστηρίζει SMS ειδοποιήσεις και αυτό σε beta στάδιο. Η διαδικασία κράτησης ενός ραντεβού χωρίζεται όπως και με τα υπόλοιπα συστήματα, σε έναν οδηγό με 4-5 βήματα στα οποία ο χρήστης επιλέγει σε ποια υπηρεσία και σε ποιόν υπάλληλο θέλει να κλείσει ραντεβού. Είναι πολύ εύκολο στην χρήση και υποστηρίζει plugins για το WordPress και το Facebook. - -Παρατηρήσεις: επί πληρωμή, υποστήριξη SMS, λειτουργία με WordPress και Facebook, δεν μπορεί να εξάγει τα δεδομένα του σε άλλη εφαρμογή (Google Calendar, Outlook) - -\href{http://www.setmore.com/}{www.setmore.com} - -\subsection{Υπόλοιπα συστήματα} -Εκτός των αναφερθέντων υπάρχουν πολλές άλλες εφαρμογές διαθέσιμες προς το κοινό. Μερικές από αυτές αναφέρονται στην παρακάτω λίστα: -\begin{enumerate} -\item SnapAppointments -\item Doodle -\item Bookeo -\item ScheduleOnce -\item BookingBug -\item SetSter -\item Agreedo -\item BookedIn -\item Book'd -\item Schedulista -\end{enumerate} - -\section{Σε τι διαφέρει από τις υπόλοιπες η προτεινόμενη λύση} -Το Easy!Appointments έχει ως σκοπό να αυτοματοποιήσει την διαδικασία της κράτησης και διαχείρισης ραντεβού για οποιαδήποτε επιχείρηση. Χρησιμοποιώντας τις δυνατότητες που μας παρέχει το διαδίκτυο μπορεί να υλοποιηθεί ένα σύστημα το οποίο να έχει την δυνατότητα να οργανώσει τα επαγγελματικά πλάνα πολλών υπαλλήλων ταυτόχρονα, επιφέροντας έτσι όχι μόνο την μείωση του χρόνου που απαιτούσαν οι παλιές μέθοδοι διαχείρισης ραντεβού, αλλά και την αύξηση της παραγωγικότητας της επιχείρησης. Οι πελάτες δεν θα χρειάζεται πλέον να τηλεφωνούν ή να πηγαίνουν στο κατάστημα αλλά θα μπορούν να βλέπουν τις διαθέσιμες ώρες της επιχείρησης και να κλείνουν το ραντεβού τους την επιθυμητή ημερομηνία και ώρα μέσω του υπολογιστή και του internet. Αυτό έχει ως αποτέλεσμα την ποιοτικότερη αλλά και αποδοτικότερη εξυπηρέτηση τους. Επιπρόσθετα βελτιώνεται η επικοινωνία και η οργάνωση των συντελεστών της επιχείρησης, παρέχοντας δυνατότητες αρχειοθέτησης και διαχείρισης των δεδομένων που αποθηκεύονται στο σύστημα ανά πάσα στιγμή και σε οποιοδήποτε μέρος. Σε αντίθεση με τα άλλα συστήματα, προσφέρει επιπλέον τα εξής: - -\begin{enumerate} -\item {\bf Αυτόνομη Εγκατάσταση:} Η επιχείρηση που θέλει να χρησιμοποιήσει την εφαρμογή θα μπορεί να την εγκαταστήσει στον server της και να την τρέξει μαζί με κάποιο άλλο site, έχοντας έτσι πλήρη πρόσβαση στα δεδομένα και τον κώδικα. Η διαδικασία της εγκατάστασης και παραμετροποίησης είναι παρόμοια με άλλα συστήματα (Joomla, WordPress κτλ) και όσο πιο αυτοματοποιημένη γίνεται. - -\item {\bf Διαμόρφωση Πλάνου Πάροχου:} Το σύστημα θα έχει ενσωματωμένη δυνατότητα δημιουργίας ημερολογιακού πλάνου εργασίας για τον κάθε πάροχο υπηρεσιών. Το πλάνο αυτό θα αποτελεί την βάση της κάθε εβδομάδας και από εκεί και πέρα ο διαχειριστής θα μπορεί να πραγματοποιήσει αλλαγές ανάλογα με τις εκάστοτε ανάγκες. - -\item {\bf Υποστήριξη Γραμματείας:} Αν παρόλα αυτά η εταιρεία ορίσει κάποια γραμματέα ως υπεύθυνη των ραντεβού, τότε είναι απαραίτητο να μπορεί να διαχειρίζεται μόνο τις εγγραφές που αντιστοιχούν στους πάροχους που βρίσκονται στην αρμοδιότητα της καθώς και τους πελάτες που είναι καταχωρημένοι στο σύστημα. Το Easy!Appointments υποστηρίζει την δημιουργία χρηστών που αντιπροσωπεύουν αυτόν τον σκοπό. - -\item {\bf Αμφίδρομος Συγχρονισμός με το Google Calendar:} Το σύστημα υποστηρίζει τον αμφίδρομο συγχρονισμό ραντεβού με το Google Calendar κάνοντας χρήση του Google Calendar API. Με αυτόν τον τρόπο η διαχείριση των ραντεβού μπορεί να γίνει ακόμα πιο εύκολη, λαμβάνοντας υπόψιν το πόσο δημοφιλής είναι η συγκεκριμένη υπηρεσία της Google. -\end{enumerate} - diff --git a/doc/thesis/includes/unit-testing.tex b/doc/thesis/includes/unit-testing.tex deleted file mode 100644 index aa2f1ed7..00000000 --- a/doc/thesis/includes/unit-testing.tex +++ /dev/null @@ -1,47 +0,0 @@ -%% ΕΛΕΓΧΟΣ ΣΥΣΤΗΜΑΤΟΣ -%% Το μέρος του εγγράφου αυτού περιέχει την περιγραφή της διαδικασίας -%% ελέγχου που χρησιμοποιείθηκε για την διασφάλιση της σωστής λειτουργίας -%% της εφαρμογής. - -\chapter{Έλεγχος Συστήματος} -Σε κάθε τομέα παραγωγής προϊόντων είναι πολύ σημαντικό να παράγονται προϊόντα τα οποία να τηρούν πάντα τις προδιαγραφές τους και να μπορούν να αντεπεξέλθουν στις απαιτήσεις του καταναλωτικού κοινού. Η φήμη και η εμπιστοσύνη που προσδίδει μια εταιρεία είναι κομβικά χαρακτηριστικά για την βιωσιμότητας της. Κάθε επαγγελματίας είναι απαραίτητο να είναι σε θέση να εγγυηθεί για την ποιότητα του προϊόντος ή της υπηρεσίας που παρέχει ως αντάλλαγμα της αμοιβής του. - -Ο τρόπος διασφάλισης της ποιότητας διαφέρει ανάλογα με την φύση του προϊόντος ή της υπηρεσίας και μπορεί να εκτελεστεί με διάφορους μεθόδους. Για παράδειγμα αν το προϊόν ήταν κάποιο τρόφιμο η εταιρία θα έπρεπε να είναι σίγουρη ότι είναι σε άριστη κατάσταση πριν φτάσει στο τραπέζι του καταναλωτή, διότι αν δεν το έκανε αυτό θα υπήρχαν επιπλοκές στην υγεία των καταναλωτών. Αντίστοιχα μια εταιρία που παρέχει μια υπηρεσία πρέπει να διασφαλίσει και να ελέγξει την ποιότητα παροχής της υπηρεσίας με διάφορους τρόπους. Ένας από αυτούς θα ήταν να λαμβάνει τις παρατηρήσεις των καταναλωτών αφότου λάβουν την υπηρεσία ή να περνάει από εσωτερικές εξετάσεις και εκπαίδευση τους υπαλλήλους της έτσι ώστε να είναι σίγουρη ότι αυτοί θα μπορούν να παρέχουν σωστά και αξιόπιστα την υπηρεσία στους πελάτες. - -Στην διαδικασία ανάπτυξης λογισμικού υπάρχουν αντίστοιχα διάφοροι τρόποι ελέγχου ότι το λογισμικό που αναπτύσσεται τηρεί τις προδιαγραφές του. Κάποιοι από αυτούς τους τρόπους είναι τα unit testing, fuzz testing, δημοσίευση δοκιμαστική έκδοσης (beta version) κ.α. Το πιο κοντινό εργαλείο ελέγχου στον προγραμματιστή είναι η διαδικασία unit testing η οποία εφαρμόζεται αποκλειστικά σε αντικειμενοστραφή κώδικα. Παρακάτω θα γίνει μια ανάλυση αυτής της τεχνικής ελέγχου και θα αναφερθούν οι μέθοδοι και η διαδικασία ελέγχου πάνω στο Easy!Appointments. - -\section {Unit testing} -Για την υλοποίηση unit tests πάνω στον κώδικα είναι απαραίτητο να τηρούνται δύο πράγματα: (1) η αντικειμενοστραφείς δομή και (2) η χρήση κάποιας βιβλιοθήκης ή εργαλείου το οποίο μπορεί να βοηθήσει στην οργάνωση και καλύτερη υλοποίηση των tests. - -Με τον όρο unit testing εννοείται η δοκιμή μίας “λειτουργικής μονάδας” του λογισμικού που αναπτύσσεται. Η κάθε λειτουργική μονάδα απομονώνεται από τις υπόλοιπες και δοκιμάζεται ξεχωριστά σε διάφορες καταστάσεις. Για αυτόν τον λόγο είναι απαραίτητο ο κώδικας να έχει αντικειμενοστραφής δομή. Η διαδικασία χωρίζεται στην συγγραφή πολλαπλών unit test, συναρτήσεων δηλαδή που δοκιμάζουν μια διαδικασία για συγκεκριμένες τιμές εισόδου. Σε κάθε περίπτωση στόχος είναι να υπάρχει ελεγχόμενη έξοδος έτσι ώστε να μπορέσει ο προγραμματιστής να είναι σίγουρος ότι το σύστημα θα λειτουργήσει σωστά σε οποιαδήποτε κατάσταση και αν βρίσκεται. Κατά την διαδικασία αυτήν μπορούν να βρεθούν πολύ εύκολα πολλά προβλήματα και ασυνέπειες στον κώδικα ενός συστήματος, τα οποία χρειάζεται να αντιμετωπιστούν. - -Για να μπορέσουν να υλοποιηθούν αυτά τα test είναι απαραίτητο να χρησιμοποιηθεί κάποια βιβλιοθήκη ή εργαλείο το οποίο θα κατέχει τις βασικές συναρτήσεις ελέγχου αποτελεσμάτων και επιπρόσθετα λειτουργίες για την παραγωγή αναφορών, οι οποίες περιέχουν τα αποτελέσματα των δοκιμών. Υπάρχουν πάρα πολλά εργαλεία που κάνουν αυτήν την δουλειά, το καθένα για μια συγκεκριμένη γλώσσα προγραμματισμού. Τα πιο διαδεδομένα εργαλεία είναι αυτά που ανήκουν στην οικογένεια xUnit (JUnit, CppUnit, NUnit κ.α). - -Τα εργαλεία αυτά μπορούν συνήθως κάλλιστα να συνεργαστούν μαζί με άλλα εργαλεία ανάπτυξης έτσι ώστε να είναι πολύ εύκολο για τον προγραμματιστή να συμπεριλάβει την διαδικασία unit testing στην υλοποίηση του κάθε συστήματος. - -\section {Easy!Appointments testing} -Η συγγραφή των unit tests για το Easy!Appointments έγινε με την χρήση της ενσωματωμένης βιβλιοθήκης που παρέχει το CodeIgniter. Η βιβλιοθήκη παρέχει τις βασικές λειτουργίες ελέγχου και παραγωγής αναφορών για τα tests του κώδικα. Προτιμήθηκε έναντι του phpunit λόγω της καλύτερης απόδοσης σε σχέση με το CodeIgniter Framework. - -Η διαδικασία της δοκιμής του συστήματος ξεκίνησε από τα models, τις λειτουργικές μονάδες που διαχειρίζονται την κίνηση των δεδομένων προς και από την βάση δεδομένων. Είναι απαραίτητο για το σύστημα να κατέχει ακέραια δεδομένα μιας και όλη η εφαρμογή βασίζεται σε αυτά. Η κάθε μέθοδος του κάθε model δοκιμάστηκε ξεχωριστά από τις υπόλοιπες για 3-5 διαφορετικές περιπτώσεις. Όσο αναπτύσσεται το σύστημα τόσο αυξάνονται και unit tests. - -\begin{figure}[h] -\centering -\includegraphics[width=150mm]{images/ea-unit-testing.png} -\caption{Στιγμιότυπο της σελίδας εμφάνισης αποτελεσμάτων των unit tests.} -\label{ea-unit-testing} -\end{figure} - -Για να γίνει αυτόματη εκτέλεση όλων των unit test που αντιστοιχούν σε ένα συγκεκριμένο model γράφτηκε η παρακάτω μέθοδος η οποία αφού ελέγξει τα ονόματα των test μεθόδων, εκτελεί μόνο εκείνα τα οποία ξεκινούν από την λέξη "test". Έτσι αν κάποια μέθοδος δεν είναι έτοιμη ή δεν πρέπει να συμπεριληφθεί στην εκτέλεση των unit test αρκεί να αλλάξει την αρχή του ονόματος της και η μέθοδος δεν θα την λάβει υπόψιν. - -\lstinputlisting{snippets/unit_test_automation.php} - -\section {Παραδείγματα} -Στον παρακάτω κώδικα δοκιμάζεται η βασική ροή της περίπτωσης χρήσης “προσθήκη ραντεβού”. Σε αυτό το test case η είσοδος της μεθόδου add() είναι σωστή και αναμένεται ότι και το αποτέλεσμα της διαδικασίας θα είναι επιτυχές. Στο τέλος αφαιρείται η εγγραφή που προστέθηκε για να μην μείνουν κατάλοιπα στην βάση. Σε κάθε unit test χρησιμοποιείται μόνο μια μέθοδος του model. Έτσι το κάθε test δεν επηρεάζεται από τυχόν προβλήματα σε άλλες μεθόδους του model. - -\lstinputlisting{snippets/unit_test_insert_example.php} - -Στο παρακάτω unit test δοκιμάζεται η μέθοδος get\_value() η οποία επιστρέφει την τιμή ενός πεδίου από την βάση. Στο συγκεκριμένο test case δίνεται ως παράμετρος ένα id εγγραφής το οποίο δεν υπάρχει στην βάση. Η αναμενόμενη συμπεριφορά από το model είναι να εμφανιστεί ένα exception το οποίο να ειδοποιεί ότι η εγγραφή με το συγκεκριμένο id δεν βρέθηκε στην βάση. - -\lstinputlisting{snippets/unit_test_get_value_example.php} - -Κάποια unit test δοκιμάζουν τις μεθόδους για σωστές τιμές και αναμένουν την επιτυχή ολοκλήρωση των διαδικασιών τους. Τα περισσότερα όμως tests σκοπό έχουν να δουν την συμπεριφορά του συστήματος για τιμές οι οποίες δεν είναι φυσιολογικές. Με αυτόν τον τρόπο μπορούν να προβλεφθούν πολλά bug και άλλα προβλήματα στον κώδικα και η εφαρμογή να είναι περισσότερο αξιόπιστη και δυνατή απέναντι σε σφάλματα. \ No newline at end of file diff --git a/doc/thesis/includes/usage-scenarios.tex b/doc/thesis/includes/usage-scenarios.tex deleted file mode 100644 index 6b0a89db..00000000 --- a/doc/thesis/includes/usage-scenarios.tex +++ /dev/null @@ -1,22 +0,0 @@ -%% ΣΕΝΑΡΙΑ ΧΡΗΣΗΣ -%% Σε αυτό το κεφάλαιο γίνεται περιγραφή ενός σεναρίου χρήσης του συστήματος -%% για κάθε έναν από τους ρόλους των χρηστών της εφαρμογής. - -\chapter{Σενάρια Χρήσης} -Το κεφάλαιο αυτό έχει ως στόχο να δώσει μια τυπική περιγραφή της χρήσης της εφαρμογής για όλους τους διαθέσιμους ρόλους των χρηστών της, έτσι ώστε να γίνει περισσότερο κατανοητός ο τρόπος με τον οποίον λειτουργεί το σύστημα κρατήσεων ραντεβού. - -%% ΣΕΝΑΡΙΟ ΧΡΗΣΗΣ ΔΙΑΧΕΙΡΙΣΤΗ -\section{Σενάριο χρήσης διαχειριστή} -Μετά από αρκετό καιρό χρήσης του Easy!Appointments η εταιρεία προσθέτει μια νέα υπηρεσία στο ενεργητικό της και για τον σκοπό αυτό ανοίγει ένα νέο τμήμα υπαλλήλων. Ο διαχειριστής του συστήματος πρέπει να ενημερώσει την εφαρμογή και να προσθέσει την νέα υπηρεσία καθώς και τους νέους πάροχους υπηρεσιών, έτσι ώστε να μπορούν οι πελάτες να κλείνουν ραντεβού μαζί τους από εδώ και πέρα. Εφόσον γίνει αυτό οι πελάτες θα μπορούν να επιλέξουν τις αντίστοιχες εγγραφές από την φόρμα κράτησης ραντεβού. - -%% ΣΕΝΑΡΙΟ ΧΡΗΣΗ ΠΑΡΟΧΟΥ ΥΠΗΡΕΣΙΩΝ -\section{Σενάριο χρήσης πάροχου υπηρεσιών} -Ο πάροχος υπηρεσιών της εφαρμογής λαμβάνει μια ειδοποίηση από την εφαρμογή (email) ότι έχει γίνει μια κράτηση για ραντεβού. Βλέποντας τα στοιχεία της κράτησης και την ημερομηνία αποφασίζει ότι δεν θα μπορέσει να είναι εκείνη την στιγμή διαθέσιμος, οπότε συνδέεται στην εφαρμογή και αλλάζει την ημερομηνία του ραντεβού. Αμέσως μετά πηγαίνει στο πρόγραμμά του και ενημερώνει την χρονική στιγμή στην οποία δεν θα είναι διαθέσιμος έτσι ώστε να μην μπορούν πλέον οι πελάτες να κάνουν κρατήσεις σε εκείνη την χρονική περίοδο. Στην συνέχεια αποστέλλεται ειδοποίηση στον πελάτη και αυτός μπορεί να κρίνει αν τον βολεύει η νέα ημερομηνία. Αν όχι θα πρέπει να ακυρώσει το ραντεβού και να το ξανά-προσθέσει σε κάποια άλλη χρονική στιγμή. - -%% ΣΕΝΑΡΙΟ ΧΡΗΣΗΣ ΠΕΛΑΤΗ -\section{Σενάριο χρήσης πελάτη} -Ο πελάτης ενδιαφέρεται να κλείσει ραντεβού στην επιχείρηση για μια συγκεκριμένη υπηρεσία. Πηγαίνει στην σελίδα της επιχείρησης και βλέπει το πλάνο, αφού έχει επιλέξει ποια υπηρεσία και ποιόν υπάλληλο επιθυμεί. Στην συνέχεια επιλέγει μια χρονική στιγμή που τον βολεύει και την κατοχυρώνει. Η διαδικασία ολοκληρώνεται με την αποστολή ενός email προς τον πελάτη το οποίο περιέχει όλες τις πληροφορίες του ραντεβού, έτσι ώστε να είναι πάντα προσβάσιμες. Σε αυτό το email περιέχεται και ένας υπερσύνδεσμος ο οποίος επιτρέπει στον πελάτη να πραγματοποιήσει αλλαγές στο ραντεβού. Από την στιγμή αυτήν και μετά το ραντεβού έχει κατοχυρωθεί και ο πελάτης θα ενημερώνεται για οποιαδήποτε αλλαγή μπορεί να γίνει στο ραντεβού του με email. - -%% ΣΕΝΑΡΙΟ ΧΡΗΣΗΣ ΓΡΑΜΜΑΤΕΑ -\section{Σενάριο χρήσης γραμματέα} -Ένας από τους πάροχους υπηρεσίας έχει κλειστεί εντελώς από ραντεβού και δεν μπορεί να δεχτεί άλλα για αυτήν την εβδομάδα. Ένας άλλος πάροχος προσφέρεται να βοηθήσει και έτσι κάποια ραντεβού πρέπει να μεταφερθούν στο ημερολογιακό πλάνο του δεύτερου πάροχου. Την διαδικασία αυτήν θα πρέπει να την αναλάβει η γραμματεία γιατί όλοι οι άλλοι είναι πολύ απασχολημένοι με το να εξυπηρετήσουν τους πελάτες τους. \ No newline at end of file diff --git a/doc/thesis/includes/use-cases.tex b/doc/thesis/includes/use-cases.tex deleted file mode 100644 index 41ab895f..00000000 --- a/doc/thesis/includes/use-cases.tex +++ /dev/null @@ -1,162 +0,0 @@ -%% ΠΕΡΙΓΡΑΦΗ ΠΕΡΙΠΤΩΣΕΩΝ ΧΡΗΣΗΣ -%% Σε αυτό το κεφάλαιο γίνεται αναλυτική περιγραφή των περιπτώσεων χρήσης -%% του συστήματος κρατήσεων ραντεβου (βασική και εναλλακτικές ροές). - -\chapter{Περιπτώσεις Χρήσης} -Σε αυτό το κεφάλαιο θα γίνει η αναλυτική περιγραφή των περιπτώσεων χρήσης του συστήματος που υλοποιήθηκε. Θα περιγραφούν τόσο η βασική ροή όσο και οι εναλλακτικές ροές για όλες τις περιπτώσεις χρήσης. Το κεφάλαιο χωρίζεται σε τμήματα ανάλογα με τον ρόλο (actor) της εφαρμογής στον οποίο ανήκουν. - -\section{Πελάτης} -\subsection{Κράτηση ραντεβού} -Η βασικότερη περίπτωση χρήσης της εφαρμογής είναι η διαδικασία της κράτησης ραντεβού του πελάτη με έναν πάροχο υπηρεσίας για την υπηρεσία που τον ενδιαφέρει. Πρόκειται για την κυριότερη περίπτωση χρήσης, μιας και το σύστημα έχει ως στόχο την ευκολότερη διαχείριση των ραντεβού με τους πελάτες. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο χρήστης μπαίνει στην σελίδα κράτησης ραντεβού και επιλέγει την υπηρεσία και τον πάροχο που τον ενδιαφέρει. Στην συνέχεια θα χρειαστεί να επιλέξει μια από τις διαθέσιμες ημερομηνίες και ώρες για να κλείσει το ραντεβού του. Αφού γίνει και αυτό θα πρέπει να συμπληρώσει τα στοιχεία του στην φόρμα που θα εμφανιστεί έτσι ώστε να μπορέσει η εταιρεία να έρθει σε επαφή μαζί του αν χρειαστεί. Τέλος ένα email θα σταλθεί πίσω στον πελάτη ότι το ραντεβού του έχει καταχωρηθεί με επιτυχία. Σε αυτό το email θα εμπεριέχεται και ένα link το οποίο θα του επιτρέπει να κάνει τροποποιήσει ή και να ακυρώσει το συγκεκριμένο ραντεβού. - -\textbf{ΕΝΑΛΛΑΚΤΙΚΕΣ ΡΟΕΣ} - -\begin{itemize} -\item Αν ο πελάτης αργήσει να επιλέξει ημερομηνία και στο ενδιάμεσο τον προλάβει ένας άλλος θα πρέπει να επιστραφεί μήνυμα το οποίο θα τον προτρέψει να βρει άλλη ημερομηνία και ώρα για το ραντεβού του. -\item Όταν ο πελάτης συμπληρώσει τα στοιχεία του και αφήσει κενό ένα πεδίο το οποίο είναι υποχρεωτικό για να ολοκληρωθεί η διαδικασία, θα εμφανιστεί μήνυμα το οποίο θα τον προτρέψει να συμπληρώσει όλα τα υποχρεωτικά πεδία. -\end{itemize} - -\begin{figure}[ht!] -\centering -\includegraphics[width=130mm]{images/book-appointment.jpg} -\caption{Σελίδα κράτησης ραντεβού.} -\label{book-appointment} -\end{figure} - -\begin{figure}[ht!] -\centering -\includegraphics[width=130mm]{images/backend-calendar.jpg} -\caption{Σελίδα διαχείρισης ραντεβού.} -\label{backend-calendar} -\end{figure} - -\begin{figure}[ht!] -\centering -\includegraphics[width=130mm]{images/backend-providers.jpg} -\caption{Σελίδα διαχείρισης πάροχων υπηρεσιών.} -\label{backend-providers} -\end{figure} - -\begin{figure}[ht!] -\centering -\includegraphics[width=130mm]{images/backend-settings.jpg} -\caption{Σελίδα ρυθμίσεων συστήματος.} -\label{book-settings} -\end{figure} - -\subsection{Επεξεργασία - ακύρωση ραντεβού} -Εφόσον καταχωρηθεί ένα ραντεβού είναι πολύ σημαντικό να μπορέσει και να τροποποιηθεί με κάποιον τρόπο. Το σύστημα από την στιγμή που καταχωρεί ένα ραντεβού κρατάει και τα στοιχεία του πελάτη σε μια εγγραφή. Παρ' όλα αυτά δεν θα ήταν καλό να αναγκάζει τον πελάτη να δημιουργεί νέο χρήστη (με username και password) έτσι ώστε να μπορέσει να κάνει αλλαγές. Κάτι τέτοιο θα μείωνε την αποδοτικότητα της εφαρμογής μιας και προσθέτει ένα επιπλέον βήμα στην όλη διαδικασία, το οποίο μάλιστα θεωρείται εκνευριστικό αφού ένας μέσος χρήστης του διαδικτύου θα χρειαστεί να δημιουργήσει δεκάδες λογαριασμούς σε διάφορες ιστοσελίδες. Λαμβάνοντας αυτά υπόψιν για να μπορέσει ο πελάτης να πραγματοποιήσει αλλαγές ή και ακύρωση σε κάποιο ραντεβού του θα ακολουθεί έναν μοναδικό σύνδεσμο ο οποίος θα του έρχεται με email. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο χρήστης ολοκληρώνει την διαδικασία κράτησης ραντεβού. Σε αυτήν την διαδικασία έχει ήδη δώσει το email του στο οποίο στέλνεται ένα email με τις πληροφορίες του ραντεβού που έχει κάνει κράτηση και μαζί έναν σύνδεσμο ο οποίος επιτρέπει στον χρήστη να πραγματοποιήσει αλλαγές στο συγκεκριμένο ραντεβού ή και να το ακυρώσει. Αφού ο χρήστης ακολουθήσει τον σύνδεσμο θα βρεθεί σε μια σελίδα η οποία θα περιέχει τις πληροφορίες του ραντεβού και θα του επιτρέπει να πραγματοποιήσει αλλαγές. Όταν ολοκληρώσει την διαδικασία θα πατάει ένα κουμπί το οποίο θα αποθηκεύει τις αλλαγές και ένα νέο email θα έρχεται πάλι στον χρήστη αλλά και στον συγκεκριμένο πάροχο ότι έχουν πραγματοποιηθεί αλλαγές στο πλάνο του. - -\textbf{ΕΝΑΛΛΑΚΤΙΚΕΣ ΡΟΕΣ} - -\begin{itemize} -\item Ο χρήστης μπορεί εν τέλη να μην θέλει να αποθηκεύσει τις αλλαγές του και έτσι να κλείσει την σελίδα. -\item Ο διαχειριστής του συστήματος μπορεί να έχει ορίσει ένα χρονικό περιθώριο πριν το ραντεβού, στο οποίο δεν επιτρέπεται να γίνονται αλλαγές (λόγω σταθερότητας του πλάνου). Αν ο χρήστης βρίσκεται μέσα σε αυτό το περιθώριο τότε θα εμφανιστεί μήνυμα το οποίο θα τον ενημερώνει για τον λόγο τον οποίο δεν μπορεί να πραγματοποιήσει αλλαγές στο ραντεβού του. -\end{itemize} - -\section {Πάροχος Υπηρεσιών} -\subsection {Συγχρονισμός πλάνου με το Google Calendar} -Βασικό στοιχείο για την χρησιμότητα και την απόδοση του συστήματος είναι η διαχείριση των δεδομένων να γίνεται από πολλά συστήματα. Κάτι τέτοιο μπορεί να επιτευχθεί με τον συγχρονισμό των ραντεβού με το Google Calendar API. Σε αυτό ο χρήστης θα μπορεί να πραγματοποιεί αλλαγές στο πλάνο του μέσω του Google Calendar και αυτές να εφαρμόζονται και στο σύστημα κρατήσεων ραντεβού κάνοντας έτσι την εργασία του πολύ εύκολη. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο χρήστης βλέπει το πλάνο του μέσω της υπηρεσίας Google Calendar και προσθέτει ένα συμβάν κατά την διάρκεια του οποίο δεν είναι διαθέσιμος. Έπειτα από λίγο τρέχει χειροκίνητα τον συγχρονισμό από το Easy!Appointments και αυτό ανακαλύπτει ότι υπάρχει ένα νέο συμβάν στο Google Calendar το οποίο δεν είναι καταχωρημένο στην βάση δεδομένων του. Αμέσως μετά παίρνει τα στοιχεία του νέου συμβάντος μέσω του API που παρέχει η Google και το αποθηκεύει στην βάση δεδομένων έτσι ώστε να μην είναι διαθέσιμος ο πάροχος την συγκεκριμένη χρονική στιγμή. Την επόμενη φορά που θα πάει ένας πελάτης να κλείσει ραντεβού με τον συγκεκριμένο πάροχο θα δει ότι το συγκεκριμένο χρονικό διάστημα δεν είναι διαθέσιμο. - -\textbf{ΕΝΑΛΛΑΚΤΙΚΕΣ ΡΟΕΣ} - -\begin{itemize} -\item Πιθανό είναι να γίνει μια αλλαγή σε ένα συγχρονισμένο συμβάν στο Google Calendar το οποίο όμως να έχει αλλαχθεί και στο Easy!Appointments. Σε αυτήν την περίπτωση θεωρείται ότι υπερισχύει η αλλαγή που έχει γίνει στο Easy!Appointments διότι δεν υπάρχει η δυνατότητα να ελεγχθεί και στα δύο συστήματα το ποια χρονική στιγμή έχει γίνει η τροποποίηση. -\end{itemize} - -\subsection {Διαχείριση ραντεβού} -Όπως και ο πελάτης, έτσι και ο πάροχος υπηρεσιών θα πρέπει να έχει την δυνατότητα να διαχειρίζεται τα ραντεβού του. Με αυτόν τον τρόπο θα έχει την δυνατότητα να πραγματοποιεί αλλαγές στο ημερολόγιο του, να αλλάζει την ημερομηνία των ραντεβού του και να καθορίζει το πλάνο του καταπώς τον βολεύει. Το Easy!Appointments εμφανίζει όλα τα ραντεβού σε ημερολόγιο, στο οποίο ο χρήστης μπορεί να περιηγηθεί χρονικά. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο χρήστης ενημερώνεται από τον προϊστάμενο του ότι θα πρέπει να πραγματοποιήσει κάποια εργασία σε ένα χρονικό διάστημα στο οποίο υπάρχουν καταχωρημένα ραντεβού με πελάτες της εταιρείας. Κάποια από τα ραντεβού μπορεί να τα αναλάβει κάποιος άλλος πάροχος και για αυτόν τον λόγο ο χρήστης επεξεργάζεται αυτά τα ραντεβού και αλλάζει τον πάροχο τους έτσι ώστε να μετατεθούν στο πλάνου του αντίστοιχου χρήστη. Όσα περισσέψουν θα χρειαστεί να τα μεταφέρει χρονικά ή να τα διαγράψει προτείνοντας στους πελάτες να κλείσουν κάποια άλλη στιγμή. - -\textbf{ΕΝΑΛΛΑΚΤΙΚΕΣ ΡΟΕΣ} - -\begin{itemize} -\item Καθώς ο πάροχος υπηρεσιών επεξεργάζεται ένα ραντεβού μπορεί να αποφασίσει ότι δεν θέλει να αποθηκεύσει τις αλλαγές που έχει κάνει και έτσι πατάει το κουμπί ακύρωσης αποτρέποντας την ενημέρωση των δεδομένων στην βάση. -\item Σε αντίθεση με τον πελάτη, ένας πάροχος υπηρεσιών μπορεί να αλλάξει την διάρκεια ενός ραντεβού ανεξάρτητα από το πόση ώρα διαρκεί η υπηρεσία που θα παρέχει. Οπότε στην φόρμα επεξεργασίας ενός ραντεβού υπάρχει η δυνατότητα επιλογής ημερομηνίας και ώρας έναρξης και τερματισμού του ραντεβού. -\end{itemize} - -\subsection{Λήψη ειδοποιήσεων από το σύστημα} -Κάθε φορά που πραγματοποιείται μια ενέργεια που αφορά κάποιο ραντεβού στο σύστημα ο πάροχος υπηρεσίας θα ενημερώνεται με email (εκτός και αν απενεργοποιήσει αυτήν την ρύθμιση). Έτσι θα είναι πάντα ενήμερος σχετικά με την κατάσταση των ραντεβού του. Σε αυτά τα μηνύματα θα περιέχεται και ένα μοναδικό link το οποίο θα δίνει την δυνατότητα στον πάροχο να πραγματοποιήσει αλλαγές γρήγορα στο ραντεβού που τον ενδιαφέρει. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο πάροχος υπηρεσιών μπαίνει στο σύστημα και πραγματοποιεί αλλαγές σε ένα ήδη καταχωρημένο ραντεβού. Με την αποθήκευση των αλλαγών αυτός και ο πελάτης θα λάβουν ένα email στο οποίο θα φαίνονται τα νέα στοιχεία του ραντεβού. Με αυτόν τον τρόπο μπορεί να επαληθευθεί ότι οι αλλαγές που έγιναν είναι σωστές και επίσης δίνεται η δυνατότητα στον χρήστη να χρησιμοποιήσει το link του ραντεβού για να πραγματοποιήσει άλλες αλλαγές, αν αυτό είναι απαραίτητο. - -\subsection {Διαχείριση Πελατών} -Από την στιγμή που ένας πάροχος θα έχει το δικαίωμα να επεξεργαστεί τις πληροφορίες ενός ραντεβού θα μπορεί να επεξεργάζεται και τα στοιχεία των πελατών που υπάγονται σε αυτό. Με αυτήν την δυνατότητα θα μπορεί να είναι σε θέση να ενημερώσει κάποια πεδία στην εγγραφή του πελάτη τα οποία είναι πιθανώς λανθασμένα ή και να προσθέσει νέες πληροφορίες. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο πάροχος μπαίνει στο σύστημα και επιλέγει να επεξεργαστεί κάποιο ραντεβού. Στην οθόνη επεξεργασίας του ραντεβού θα μπορέσει να τροποποιήσει και τα στοιχεία των πελατών. Όταν είναι έτοιμος μπορεί να αποθηκεύσει τις αλλαγές στην βάση δεδομένων. - -\textbf{ΕΝΑΛΛΑΚΤΙΚΕΣ ΡΟΕΣ} - -Ο πάροχος μπορεί να αλλάξει τα στοιχεία ενός πελάτη χωρίς να πραγματοποιήσει αλλαγές στις πληροφορίες του ραντεβού του ίδιου. - -\section{Γραμματέας} -\subsection{Διαχείριση ραντεβού} -Ο χρήστης γραμματέας μπορεί να πραγματοποιήσει αλλαγές στα ραντεβού ενός ή περισσοτέρων πάροχων υπηρεσίας. Με αυτόν τον τρόπο μια εταιρεία μπορεί να αναθέσει όλη την διαχείριση των ραντεβού σε ένα άτομο και οι πάροχοι απλώς να βλέπουν τα ραντεβού τους στο πλάνο. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο χρήστης γραμματέας δέχεται τηλεφώνημα από κάποιον πελάτη ο οποίος επιθυμεί να αλλάξει την ώρα του ραντεβού του αλλά δεν έχει σύνδεση με το διαδίκτυο στο σημείο που βρίσκεται. Έτσι ο γραμματέας πραγματοποιεί την αλλαγή του ραντεβού καταπώς μπορεί να βολεύει τόσο τον πάροχο υπηρεσίας όσο και τον πελάτη. Όταν τελειώσει μπορεί να αποθηκεύσει τις αλλαγές στο σύστημα. - -\subsection{Διαχείριση πελατών} -Εκτός των ραντεβού, ο χρήστης γραμματέας είναι σε θέση να πραγματοποιήσει αλλαγές και στα στοιχεία των πελατών οργανώνοντας και κρατώντας πλήρη πελατολόγιο για την επιχείριση. Μελλοντικά θα είναι σε θέση να βρίσκει πολύ εύκολα οποιονδήποτε πελάτη της επιχείρισης και να βλέπει τα στοιχεία του. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο γραμματέας πηγαίνει στο backend στην σελίδα τον πελατών και φιλτράρει τον πελάτη που τον ενδιαφέρει και αμέσως βλέπει τα στοιχεία του. Πολύ εύκολα μπορεί να πραγματοποιήσει αλλαγές αλλά και να τον διαγράψει από το σύστημα. - -\textbf{ΕΝΑΛΛΑΚΤΙΚΕΣ ΡΟΕΣ} - -\begin{itemize} -\item Ο γραμματέας μπορεί να επεξεργαστεί τα στοιχεία ενός πελάτη και την στιγμή που επεξεργάζεται ένα ραντεβού. Παρόλα αυτά σε αυτήν την περίπτωση κυρίαρχη οντότητα είναι το ραντεβού και έτσι ο χρήστης δεν έχει την δυνατότητα να φιλτράρει τους πελάτες καταπώς θέλει. Επίσης ένας πελάτης μπορεί να διαγραφεί μόνο όταν διαγραφεί και το ραντεβού του. -\end{itemize} - -\section{Διαχειριστής} -\subsection{Εγκατάσταση της εφαρμογής} -Αυτή η περίπτωση χρήσης περιλαμβάνει την ρύθμιση του server όπου θα τρέξει το Easy!Appointments και την δημιουργία του λογαριασμού του διαχειριστή. Επίσης μπορεί να καθοριστούν και τα κλειδιά που απαιτούνται για την χρήση του Google Calendar API. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο διαχειριστής τοποθετεί τα αρχεία της εφαρμογής στον server του και πηγαίνει με τον περιηγητή στην διεύθυνση που δείχνει τον κύριο κατάλογο. Η εφαρμογή καταλαβαίνει ότι δεν έχει ακόμα πραγματοποιηθεί εγκατάσταση και μεταφέρει τον χρήστη στην διαδικασία εγκατάστασης. Σε αυτήν την διαδικασία ο διαχειριστής θα πρέπει να ορίσει σημαντικά στοιχεία που αφορούν την λειτουργία του συστήματος και τα στοιχεία του λογαριασμού του. Όλα αυτά τα στοιχεία βέβαια θα είναι διαθέσιμα προς επεξεργασία από την αντίστοιχη σελίδα στο backend. - -\subsection{Παραμετροποίηση της εφαρμογής} -Για να μπορέσει να λειτουργήσει η εφαρμογή σύμφωνα με την μορφή της επιχείρησης θα χρειαστεί να παραμετροποιηθεί από τον διαχειριστή. Η παραμετροποίηση περιλαμβάνει τα ωράρια λειτουργίας της επιχείρησης, την διαχείριση των υπηρεσιών που θα είναι διαθέσιμες προς το κοινό καθώς και την διαχείριση των πάροχων υπηρεσιών. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο διαχειριστής εισέρχεται στο backend μέρος της εφαρμογής και επιλέγει την σελίδα των ρυθμίσεων. Εκεί έχει την δυνατότητα να θέσει τις τιμές σε διάφορες παραμέτρους οι οποίες καθορίζουν τον τρόπο με τον οποίο λειτουργεί το σύστημα. Στόχος είναι αυτός να συμβαδίζει με τον τρόπο λειτουργίας της επιχείρισης έτσι ώστε να μπορεί η εταιρεία να επωφεληθεί από το Easy!Appointments. - -\subsection{Διαχείριση ραντεβού} -Ο διαχειριστής ως χρήστης έχει πρόσβαση σε όλες τις πληροφορίες του συστήματος. Έτσι μπορεί να μεταβάλει και να προσθέσει ραντεβού στο σύστημα σαν να ήταν ένας πάροχος υπηρεσιών ή ένας χρήστης γραμματέας. - -\textbf {ΒΑΣΙΚΗ ΡΟΗ} - -Ο διαχειριστής συνδέεται στο backend μέρος της εφαρμογής και πηγαίνει στην σελίδα του ημερολογίου. Εκεί μπορεί να δει τα ραντεβού όλων των πάροχων υπηρεσιών και να πραγματοποιήσει αλλαγές σε αυτά. Με το που αποθηκευτούν οι αλλαγές σε ένα ραντεβού ο πελάτης και ο πάροχος θα ενημερωθούν με email, όπως θα γινόταν δηλαδή αν την επεξεργασία την έκανε ένας πάροχος. - -\subsection {Διαχείριση χρηστών} -Τις υπηρεσίες που προσφέρει η εταιρεία τις αναλαμβάνουν κάποιοι υπάλληλοι (ή ομάδες υπαλλήλων), οι οποίοι αναφέρονται στο σύστημα ως πάροχοι υπηρεσιών. Τα στοιχεία τους και τις αρμοδιότητές τους μέσα στο σύστημα τα ορίζει μόνο ο διαχειριστής του συστήματος, από το backend μέρος της εφαρμογής. Επίσης είναι δυνατή η διαχείριση των διαχειριστών, γραμματειών και πελατών του συστήματος. - -\textbf{ΒΑΣΙΚΗ ΡΟΗ} - -Ο διαχειριστής της εφαρμογής συνδέεται στο backend και πηγαίνει στην σελίδα των πάροχων υπηρεσίας. Εκεί βλέπει μια λίστα με τους ήδη καταχωρημένους πάροχους. Αν θέλει μπορεί να προσθέσει έναν καινούργιο χρήστη ή να επεξεργαστεί και να διαγράψει κάποια εγγραφή που υπάρχει ήδη στην βάση δεδομένων. - -\subsection {Διαχείριση υπηρεσιών} -Οι πελάτες που θα επισκέπτονται τον ιστότοπο του Easy!Appointments της επιχείρησης θα κλείνουν ραντεβού για συγκεκριμένες υπηρεσίες. Το ποιες υπηρεσίες θα είναι διαθέσιμες και ποιοι πάροχοι υπηρεσιών μπορούν να εξυπηρετήσουν τι, το διαχειρίζεται ο διαχειριστής του συστήματος. Αποτελεί υποπερίπτωση χρήσης της παραμετροποίησης της εφαρμογής. \ No newline at end of file diff --git a/doc/thesis/presentation.odp b/doc/thesis/presentation.odp deleted file mode 100644 index 11056154..00000000 Binary files a/doc/thesis/presentation.odp and /dev/null differ diff --git a/doc/thesis/presentation.pdf b/doc/thesis/presentation.pdf deleted file mode 100644 index 0f1bfd43..00000000 Binary files a/doc/thesis/presentation.pdf and /dev/null differ diff --git a/doc/thesis/snippets/find_record_id.php b/doc/thesis/snippets/find_record_id.php deleted file mode 100644 index 16da53a0..00000000 --- a/doc/thesis/snippets/find_record_id.php +++ /dev/null @@ -1,30 +0,0 @@ -db - ->select('ea_users.id') - ->from('ea_users') - ->join('ea_roles', 'ea_roles.id = ea_users.id_roles', 'inner') - ->where('ea_users.email', $admin['email']) - ->where('ea_roles.slug', DB_SLUG_ADMIN) - ->get(); - - if ($result->num_rows() == 0) { - throw new Exception('Could not find admin record id.'); - } - - return intval($result->row()->id); -} \ No newline at end of file diff --git a/doc/thesis/snippets/google_sync_algorithm.php b/doc/thesis/snippets/google_sync_algorithm.php deleted file mode 100644 index 1e67e1f1..00000000 --- a/doc/thesis/snippets/google_sync_algorithm.php +++ /dev/null @@ -1,168 +0,0 @@ -load->library('session'); - if ($this->session->userdata('user_id') == FALSE) return; - - if ($provider_id === NULL) { - throw new Exception('Provider id not specified.'); - } - - $this->load->model('appointments_model'); - $this->load->model('providers_model'); - $this->load->model('services_model'); - $this->load->model('customers_model'); - $this->load->model('settings_model'); - - $provider = $this->providers_model->get_row($provider_id); - - // Check whether the selected provider has google sync enabled. - $google_sync = $this->providers_model - ->get_setting('google_sync', $provider['id']); - if (!$google_sync) { - throw new Exception('The selected provider has not the ' - . 'Google synchronization setting enabled.'); - } - - $google_token = json_decode($this->providers_model - ->get_setting('google_token', $provider['id'])); - $this->load->library('google_sync'); - $this->google_sync->refresh_token($google_token->refresh_token); - - // Fetch provider's appointments that belong to the sync - // time period. - $sync_past_days = $this->providers_model - ->get_setting('sync_past_days', $provider['id']); - $sync_future_days = $this->providers_model - ->get_setting('sync_future_days', $provider['id']); - $start = strtotime('-' . $sync_past_days - . ' days', strtotime(date('Y-m-d'))); - $end = strtotime('+' . $sync_future_days - . ' days', strtotime(date('Y-m-d'))); - - $where_clause = array( - 'start_datetime >=' => date('Y-m-d H:i:s', $start), - 'end_datetime <=' => date('Y-m-d H:i:s', $end), - 'id_users_provider' => $provider['id'] - ); - - $appointments = - $this->appointments_model->get_batch($where_clause); - - $company_settings = array( - 'company_name' => $this->settings_model - ->get_setting('company_name'), - 'company_link' => $this->settings_model - ->get_setting('company_link'), - 'company_email' => $this->settings_model - ->get_setting('company_email') - ); - - // Sync each appointment with Google Calendar by following - // the project's sync protocol (see documentation). - foreach($appointments as $appointment) { - if ($appointment['is_unavailable'] == FALSE) { - $service = $this->services_model - ->get_row($appointment['id_services']); - $customer = $this->customers_model - ->get_row($appointment['id_users_customer']); - } else { - $service = NULL; - $customer = NULL; - } - - // If current appointment not synced yet, add to gcal. - if ($appointment['id_google_calendar'] == NULL) { - $google_event = $this->google_sync - ->add_appointment($appointment, $provider, - $service, $customer, $company_settings); - $appointment['id_google_calendar'] = $google_event->id; - $this->appointments_model->add($appointment);// Save gcal id - } else { - // Appointment is synced with google calendar. - try { - $google_event = $this->google_sync - ->get_event($appointment['id_google_calendar']); - - if ($google_event->status == 'cancelled') { - throw new Exception('Event is cancelled, remove the ' - . 'record from Easy!Appointments.'); - } - - // If gcal event is different from e!a appointment - // then update e!a record. - $is_different = FALSE; - $appt_start = strtotime($appointment['start_datetime']); - $appt_end = strtotime($appointment['end_datetime']); - $event_start = - strtotime($google_event->getStart()->getDateTime()); - $event_end = - strtotime($google_event->getEnd()->getDateTime()); - - if ($appt_start != $event_start - || $appt_end != $event_end) { - $is_different = TRUE; - } - - if ($is_different) { - $appointment['start_datetime'] = - date('Y-m-d H:i:s', $event_start); - $appointment['end_datetime'] = - date('Y-m-d H:i:s', $event_end); - $this->appointments_model->add($appointment); - } - - } catch(Exception $exc) { - // Appointment not found on gcal, delete from e!a. - $this->appointments_model->delete($appointment['id']); - $appointment['id_google_calendar'] = NULL; - } - } - } - - // :: ADD GCAL EVENTS THAT ARE NOT PRESENT ON E!A - $events = $this->google_sync->get_sync_events($start, $end); - - foreach($events->getItems() as $event) { - $results = $this->appointments_model->get_batch( - array('id_google_calendar' => $event->getId())); - if (count($results) == 0) { - // Record doesn't exist in E!A, so add the event now. - $appointment = array( - 'start_datetime' => date('Y-m-d H:i:s', - strtotime($event->start->getDateTime())), - 'end_datetime' => date('Y-m-d H:i:s', - strtotime($event->end->getDateTime())), - 'is_unavailable' => TRUE, - 'notes' => $event->getSummary() - . ' ' . $event->getDescription(), - 'id_users_provider' => $provider_id, - 'id_google_calendar' => $event->getId(), - 'id_users_customer' => NULL, - 'id_services' => NULL, - ); - $this->appointments_model->add($appointment); - } - } - - echo json_encode(AJAX_SUCCESS); - - } catch(Exception $exc) { - echo json_encode(array( - 'exceptions' => array($exc) - )); - } -} \ No newline at end of file diff --git a/doc/thesis/snippets/provider_appointment_hours.php b/doc/thesis/snippets/provider_appointment_hours.php deleted file mode 100644 index 80dc86b0..00000000 --- a/doc/thesis/snippets/provider_appointment_hours.php +++ /dev/null @@ -1,108 +0,0 @@ -load->model('providers_model'); - $this->load->model('appointments_model'); - $this->load->model('settings_model'); - - try { - // If manage mode is TRUE then the following we should not - // consider the selected appointment when calculating the - // available time periods of the provider. - $exclude_appointments = ($_POST['manage_mode'] === 'true') - ? array($_POST['appointment_id']) - : array(); - - $empty_periods = $this->get_provider_available_time_periods( - $_POST['provider_id'], $_POST['selected_date'], - $exclude_appointments); - - // Calculate the available appointment hours for the given - // date. The empty spaces are broken down to 15 min and if - // the service fit in each quarter then a new available hour - // is added to the "$available_hours" array. - - $available_hours = array(); - - foreach ($empty_periods as $period) { - $start_hour = new DateTime($_POST['selected_date'] - . ' ' . $period['start']); - $end_hour = new DateTime($_POST['selected_date'] - . ' ' . $period['end']); - - $minutes = $start_hour->format('i'); - - if ($minutes % 15 != 0) { - // Change the start hour of the current space in - // order to be on of the following: 00, 15, 30, 45. - if ($minutes < 15) { - $start_hour->setTime($start_hour->format('H'), 15); - } else if ($minutes < 30) { - $start_hour->setTime($start_hour->format('H'), 30); - } else if ($minutes < 45) { - $start_hour->setTime($start_hour->format('H'), 45); - } else { - $start_hour->setTime($start_hour->format('H') + 1, 00); - } - } - - $current_hour = $start_hour; - $diff = $current_hour->diff($end_hour); - - while (($diff->h * 60 + $diff->i) - > intval($_POST['service_duration'])) { - $available_hours[] = $current_hour->format('H:i'); - $current_hour->add(new DateInterval("PT15M")); - $diff = $current_hour->diff($end_hour); - } - } - - // If the selected date is today, remove past hours. It is - // important include the timeout before booking that is set - // in the backoffice the system. Normally we might want the - // customer to book an appointment that is at least half or - // one hour from now. The setting is stored in minutes. - if (date('m/d/Y', strtotime($_POST['selected_date'])) - == date('m/d/Y')) { - if ($_POST['manage_mode'] === 'true') { - $book_advance_timeout = 0; - } else { - $book_advance_timeout = - $this->settings_model->get_setting('book_advance_timeout'); - } - - foreach($available_hours as $index => $value) { - $available_hour = strtotime($value); - $current_hour = strtotime('+' . $book_advance_timeout - . ' minutes', strtotime('now')); - if ($available_hour <= $current_hour) { - unset($available_hours[$index]); - } - } - } - - $available_hours = array_values($available_hours); - echo json_encode($available_hours); - - } catch(Exception $exc) { - echo json_encode(array( - 'exceptions' => array(exceptionToJavaScript($exc)) - )); - } -} \ No newline at end of file diff --git a/doc/thesis/snippets/provider_available_periods.php b/doc/thesis/snippets/provider_available_periods.php deleted file mode 100644 index 86504815..00000000 --- a/doc/thesis/snippets/provider_available_periods.php +++ /dev/null @@ -1,139 +0,0 @@ -load->model('appointments_model'); - $this->load->model('providers_model'); - - // Get the provider's working plan and reserved appointments. - $working_plan = json_decode($this->providers_model - ->get_setting('working_plan', $provider_id), true); - - $where_clause = array( - 'DATE(start_datetime)'=>date('Y-m-d', strtotime($selected_date)), - 'id_users_provider'=>$provider_id - ); - - $reserved_appointments = $this->appointments_model - ->get_batch($where_clause); - - // Sometimes it might be necessary to not take into account some - // appointment records in order to display what the providers' - // available time periods would be without them. - foreach ($exclude_appointments as $excluded_id) { - foreach ($reserved_appointments as $index => $reserved) { - if ($reserved['id'] == $excluded_id) { - unset($reserved_appointments[$index]); - } - } - } - - // Find the empty spaces on the plan. The first split between the - // plan is due to a break (if exist). After that every reserved - // appointment is considered to be a taken space in the plan. - $selected_date_working_plan = - $working_plan[strtolower(date('l', strtotime($selected_date)))]; - $available_periods_with_breaks = array(); - - if (isset($selected_date_working_plan['breaks'])) { - foreach($selected_date_working_plan['breaks'] as $index=>$break){ - // Split the working plan to available time periods that do not - // contain the breaks in them. - $last_break_index = $index - 1; - - if (count($available_periods_with_breaks) === 0) { - $start_hour = $selected_date_working_plan['start']; - $end_hour = $break['start']; - } else { - $start_hour = $selected_date_working_plan['breaks'] - [$last_break_index]['end']; - $end_hour = $break['start']; - } - - $available_periods_with_breaks[] = array( - 'start' => $start_hour, - 'end' => $end_hour - ); - } - // Add the period from the last break to the end of the day. - $available_periods_with_breaks[] = array( - 'start'=>$selected_date_working_plan['breaks'][$index]['end'], - 'end'=>$selected_date_working_plan['end'] - ); - } - - // Break the empty periods with the reserved appointments. - $available_periods_with_appointments = - $available_periods_with_breaks; - - foreach($reserved_appointments as $appointment) { - foreach($available_periods_with_appointments as $index=>&$period){ - $a_start = - date('H:i',strtotime($appointment['start_datetime'])); - $a_end = - date('H:i', strtotime($appointment['end_datetime'])); - $p_start = - date('H:i', strtotime($period['start'])); - $p_end = - date('H:i', strtotime($period['end'])); - - if ($a_start <= $p_start && $a_end <= $p_end - && $a_end <= $p_start) { - // The appointment does not belong in this time period, so - // we will not change anything. - } else if ($a_start <= $p_start && $a_end <= $p_end - && $a_end >= $p_start) { - // The appointment starts before the period and finishes - // somewhere inside.We will need to break this period and - // leave the available part. - $period['start'] = $a_end; - } else if ($a_start >= $p_start && $a_end <= $p_start) { - // The appointment is inside the time period, so we will - // split the period into two new others. - unset($available_periods_with_appointments[$index]); - $available_periods_with_appointments[] = array( - 'start' => $p_start, - 'end' => $a_start - ); - $available_periods_with_appointments[] = array( - 'start' => $a_end, - 'end' => $p_end - ); - } else if ($a_start >= $p_start && $a_end >= $p_start - && $a_start <= $p_end) { - // The appointment starts in the period and finishes out - // of it. We will need to remove the time that is taken - // from the appointment. - $period['end'] = $a_start; - } else if ($a_start >= $p_start && $a_end >= $p_end - && $a_start >= $p_end) { - // The appointment does not belong in the period so do not - // change anything. - } else if ($a_start <= $p_start && $a_end >= $p_end - && $a_start <= $p_end) { - // The appointment is bigger than the period, so this period - // needs to be removed. - unset($available_periods_with_appointments[$index]); - } - } - } - return array_values($available_periods_with_appointments); -} \ No newline at end of file diff --git a/doc/thesis/snippets/unit_test_automation.php b/doc/thesis/snippets/unit_test_automation.php deleted file mode 100644 index 6ad22712..00000000 --- a/doc/thesis/snippets/unit_test_automation.php +++ /dev/null @@ -1,15 +0,0 @@ -CI->Appointments_Model - ->get_value('start_datetime', $random_record_id); - } catch (InvalidArgumentException $db_exc) { - $has_thrown_exception = TRUE; - } - - $this->CI->unit->run($has_thrown_exception, TRUE, - 'Test get_value() with record id that does not exist.'); -} \ No newline at end of file diff --git a/doc/thesis/snippets/unit_test_insert_example.php b/doc/thesis/snippets/unit_test_insert_example.php deleted file mode 100644 index 0a39e739..00000000 --- a/doc/thesis/snippets/unit_test_insert_example.php +++ /dev/null @@ -1,31 +0,0 @@ - '2013-05-01 12:30:00', - 'end_datetime' => '2013-05-01 13:00:00', - 'notes' => 'Some notes right here...', - 'id_users_provider' => $this->provider_id, - 'id_users_customer' => $this->customer_id, - 'id_services' => $this->service_id - ); - $appointment_data['id'] = $this->CI->Appointments_Model - ->add($appointment_data); - $this->CI->unit->run($appointment_data['id'], 'is_int', - 'Test if add() appointment (insert operation) ' - . 'returned the db row id.'); - - // Check if the record is the one that was inserted. - $db_data = $this->CI->db->get_where('ea_appointments', - array('id' => $appointment_data['id']))->row_array(); - $this->CI->unit->run($appointment_data, $db_data, 'Test if add() ' - . 'appointment (insert operation) has successfully ' - . 'inserted a record.'); - - // Delete inserted record. - $this->CI->db->delete('ea_appointments', - array('id' => $appointment_data['id'])); -} \ No newline at end of file diff --git a/doc/thesis/thesis.bib b/doc/thesis/thesis.bib deleted file mode 100644 index 9c460476..00000000 --- a/doc/thesis/thesis.bib +++ /dev/null @@ -1,21 +0,0 @@ -@misc { - google_calendar_api, - title = "Google Calendar API", - url = "https://developers.google.com/google-apps/calendar/", - year = "2013" -} - -@misc { - codeigniter_reference, - author = "", - title = "CodeIgniter Reference", - url = "http://ellislab.com/codeigniter/user-guide/toc.html", - year = "2013" -} - -@misc { - software_engineering_notes, - author = "Νικόλαος Πεταλίδης", - title = "Σημειώσεις των μαθημάτων Τεχνολογία Λογισμικού 1 \& 2.", - year = "2012" -} \ No newline at end of file diff --git a/doc/thesis/thesis.pdf b/doc/thesis/thesis.pdf deleted file mode 100644 index 26913ac2..00000000 Binary files a/doc/thesis/thesis.pdf and /dev/null differ diff --git a/doc/thesis/thesis.sty b/doc/thesis/thesis.sty deleted file mode 100644 index b0bdae63..00000000 --- a/doc/thesis/thesis.sty +++ /dev/null @@ -1,454 +0,0 @@ -% ΤΕΙ Σερρών -% Σχολή Τεχνολογικών Εφαρμογών -% Τμήμα Πληροφορικής και Επικοινωνιών -% Πτυχιακή εργασία -% -% Nicholaos Petalidis, 15/08/1998 -% icdthesis.sty Style file for TEI of SERRES, ICD, final year -% dissertation thesis -% Copyright (C) yyyy name of author - -% This program is free software; you can redistribute it and/or -% modify it under the terms of the GNU General Public License -% as published by the Free Software Foundation; either version 2 -% of the License, or (at your option) any later version. - -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. - -% You should have received a copy of the GNU General Public License -% along with this program; if not, write to the Free Software -% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -%---------------------------Identification Part-------------------------------- -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{icdthesisUTF} - -%--------------------------Initial Code---------------------------------------- - -% This part is empty - -%--------------------------Declaration of Options------------------------------ -\DeclareOption{a4paper}{\setlength{\paperheight}{297mm}% - \setlength{\paperwidth}{210mm}} - -\ExecuteOptions{a4paper,12pt} -\ProcessOptions - -%-------------------------Package Loading-------------------------------------- -\RequirePackage{polyglossia} -\RequirePackage{fontspec} % necessary of XeTeX -\RequirePackage{xunicode} % Unicode from accented glyphs -\RequirePackage{xltxtra} % loads fixltx2e, etex, xunicode, fontspec -%\RequirePackage{xgreek} % for greek documents -\RequirePackage[backend=biber,bibencoding=utf8,natbib=false,bibstyle=authoryear,citestyle=authoryear,babel=hyphen]{biblatex} -\RequirePackage{ifthen} -\RequirePackage{url} -\RequirePackage{csquotes} -\RequirePackage[font=small,format=plain,labelfont=bf]{caption} -\setdefaultlanguage{greek} -\setotherlanguage{english} - -%set fonts required by the guidelines -\setmainfont[Mapping=tex-text]{Times New Roman} -\setmonofont[Mapping=tex-text]{Courier New} - -%\setmonofont[Script=Latin,Mapping=tex-text]{Courier New} -%\newfontfamily\greekfont[Script=Greek,Mapping=tex-text]{Times New Roman} -%Redefine greek font family because some fonts although they have greek glyphs they -%do not explicitly support the Greek script -\newfontfamily\greekfont[Mapping=tex-text]{Times New Roman} -\newfontfamily\greekfonttt[Mapping=tex-text]{Courier New} -\newfontfamily\greekfontsf[Mapping=tex-text]{Arial} - -\gappto\captionsgreek{\renewcommand{\figurename}{Διάγραμμα}} -\gappto\captionsgreek{\renewcommand{\listfigurename}{Κατάλογος διαγραμμάτων}} -%--------------------------- Main Code----------------------------------------- - -\typeout{----------------------------------------------------------------------} -\typeout{- Τμήμα Μηχανικών Πληροφορικής ΤΕ } -\typeout{- ΤΕΙ Κεντρικής Μακεδονίας, version 0.4, 05/11/2013 } -\typeout{- Nicholaos Petalidis, nikos petalidis.gr } -\typeout{-----------------------------------------------------------------------} - -%\tracingmacros=1 -%\tracingcommands=1 - -%-----------------------Set up margins----------------------------------------- - - % Define hoffset to be -1in. This way calculations start from 0in - % from the left side of the paper instead of 1in. - - \setlength{\hoffset}{-1in} - - % Define the left margin to be 40mm - % No need to set evensidemargin for one-sided printing - % 40mm = 114pt - \setlength{\oddsidemargin}{114pt} - - % Define the right margin to be 15mm - % Leave the marginparsep unchanged - % Set the maginparwidth to be the remaining space from marginparsep - % 25mm = 71pt - \setlength{\marginparwidth}{71pt} - \addtolength{\marginparwidth}{-\marginparsep} - \setlength{\marginparpush}{0mm} - % Calculate the textwidth: - % This is a bit difficult. The standard says there must be around 60-70 - % characters per line... I reckon that a textwidth of around 120mm - % should give 60-70 characters of 11pt size. - % On the other hand I don't like the output, (lines look too short) - % so I have put it to the maximum: 14.5mm = 413pt - - \setlength{\textwidth}{413pt} - - % An update: - % The width of the a4 : 210mm - % The width of the left margin : 40mm - % The width of the right margin: 25mm - % The width of the text: 145mm - - % The standard says ``all other margins should be at least 15mm'' - % This includes the top and bottom margin - - % Define voffset to be -1in. This way calculations start from 0in - % from the top side of the paper instead of 1in. - - \setlength{\voffset}{-1in} - - % Define the topmargin to be 15mm - % This is the minimum recommended top margin - - \setlength{\topmargin}{43pt} - - % Define the distance between the heading (page number) and the text - % to be 8mm = 23pt - - \setlength{\headsep}{23pt} - - % Define the height of a heading to be 12pt - - \setlength{\headheight}{12pt} - - % Define the distance between the bottom of a footnote and - % the bottom of the text to be 10.5mm=30pt - - \setlength{\footskip}{30pt} - - % Change the textheight so that the bottom margin is 15mm=43pt - \setlength{\textheight}{695pt} - - -%------------------Typography-------------------------------------------------- - - %Paragraphs should be indented 5-10mm with no additional space between - %paragraphs. I set the indent to be 7.5 mm - \setlength{\parindent}{7.5mm} - - %Set the spacing between lines to one and a half - \renewcommand{\baselinestretch }{1.5} - -%----------Set up commands---------------------------------------------------- -\newcommand{\thesistitle}{A title} -\newcommand{\thesisauthorsex}{male} -\newcommand{\thesisauthor}{Ένας Σπουδαστής} -\newcommand{\thesisauthorabbrv}{Ε. Σπουδαστής} -\newcommand{\thesisauthorinitials}{ΕΑ} -\newcommand{\thesisSecondAuthor}{} -\newcommand{\thesisSecondAuthorabbrv}{Ε. Σπουδαστής} -\newcommand{\thesisSecondAuthorInitials}{} -\newcommand{\thesissupervisor}{Ν. Πεταλίδης} -\newcommand{\thesismonth}{August} -\newcommand{\thesistype}{Thesis} -\newcommand{\degreetitle}{Πτυχίο} -\newcommand{\degreetitleabbr}{Πτυχίο} -\newcommand{\thesisyear}{1900} -\newcommand{\thesisschool}{Σχολή Τεχνολογικών Εφαρμογών} -\newcommand{\thesisuniversity}{ΤΕΧΝΟΛΟΓΙΚΟ ΕΚΠΑΙΔΕΥΤΙΚΟ ΙΔΡΥΜΑ ΚΕΝΤΡΙΚΗΣ ΜΑΚΕΔΟΝΙΑΣ} -\newcommand{\thesisdepartment}{Τμήμα Μηχανικών Πληροφορικής ΤΕ} - -%--------------------Format the page style------------------------------------- - %According to BS 4821 page numbers should appear at the top outer corner - % First define a heading that has a page number on the top outer corner - - \renewcommand{\ps@myheadings}{% - \renewcommand{\@oddhead}{\hfil\thepage}% - \renewcommand{\@evenhead}{\@oddhead}% - \renewcommand{\@evenfoot}{}% empty - \renewcommand{\@oddfoot}{}% empty - } - - % The standard wants page numbers to appear in the top outer corner. - % To overcome the problems with the \chapter, \tableofcontents - % pagestyles I redefine the plain page style to be that of myheadings - - \let\ps@plain=\ps@myheadings - % Apparently most definitions use @mkboth instead of markboth. - % This command does nothing in myheadings so I have to redefine it - \renewcommand{\@mkboth}{\markboth} -% **************************TITLE PAGE********************************** - -% A specimen is provided in the handbook for a title page. -% Apparenrtly the specimen is wrong and everything should be centered -% instead of being flushed-left. In that specimen the title and author -% name appears in upper case. I have it in upper case here as well. -\newcommand{\Titlepage}{ - \thispagestyle{empty} - \begin{center} - %\fontsize{12pt}{\baselineskip}\selectfont - \MakeUppercase{\textbf{\thesisuniversity}}\\ - \MakeUppercase{\textbf{\thesisschool}}\\ - \MakeUppercase{\textbf{\thesisdepartment}}\\ - \vfill - %\fontsize{16}{\baselineskip}\selectfont % The standard requires 16pt - % for the title page - \Large{\MakeUppercase{\textbf{\thesistitle}}} - %\fontsize{14}{\baselineskip}\selectfont % The standard requires 14pt - % for the title page - \vfill - \large{ - \ifthenelse{\equal{\thesisSecondAuthor}{}}{ - \ifthenelse{\equal{\thesisauthorsex}{male}} - {\textbf{Πτυχιακή εργασία του}\\\thesisauthor} - {\textbf{Πτυχιακή εργασία της}\\\thesisauthor}} - {\textbf{Πτυχιακή εργασία των}\\\thesisauthor\\\thesisSecondAuthor} - \\Επιβλέπων: \thesissupervisor} - \vfill - %\fontsize{12}{\baselineskip}\selectfont % The standard requires - \MakeUppercase{\textbf{ΣΕΡΡΕΣ, \thesismonth\ \thesisyear}} - \end{center} - % Make the default to be myheadings - \pagestyle{myheadings} -} -%********************************************************************** - -% *****************************ABSTRACT******************************** -% Not much information is provided about the abstract so I took -% the liberty of creating my own:-) -\newcommand{\thesisabstract}{Σύνοψη} -\newcommand{\@thesisabstract}{\thesisabstract} - -\newenvironment{Abstract} -{ - \chapter*{\@thesisabstract - \@mkboth{} - {}} - \addcontentsline{toc}{chapter}{\@thesisabstract} - } -{} -%********************************************************************** - -% *************************ACKNOWLEDGEMENTS**************************** -\newcommand{\thesisacknowledgementhead}{Ευχαριστίες} -\newcommand{\@thesisacknowledgementhead}{\thesisacknowledgementhead} - -\newenvironment{Acknowledgement} -{ - \chapter*{\@thesisacknowledgementhead - \@mkboth{}{}} - - \addcontentsline{toc}{chapter}{\@thesisacknowledgementhead} - } -{} -%******************************************************************** - -% ******************************PREFACE****************************** -\newcommand{\thesispreface}{Πρόλογος} -\newcommand{\@thesispreface}{\thesispreface} - -\newenvironment{Preface} -{ - \chapter*{\@thesispreface - \@mkboth{}{}} - - \addcontentsline{toc}{chapter}{\@thesispreface} - } -{ } -%********************************************************************** - -% ******************************AUTHORS DECLARATION******************** -\newcommand{\thesisdeclaration}{Υπεύθυνη δήλωση} -\newcommand{\@thesisdeclaration}{\thesisdeclaration} - -\newenvironment{Declaration} -{ - \chapter*{\@thesisdeclaration - \@mkboth{}{}} - - \addcontentsline{toc}{chapter}{\@thesisdeclaration} - } -{ } -\newcommand{\Declarationpage}{ - \vfill - \begin{Declaration} - \textbf{\underline{Υπεύθυνη Δήλωση}}: - \ifthenelse{\equal{\thesisSecondAuthor}{}}{ - Βεβαιώνω ότι είμαι συγγραφέας αυτής της πτυχιακής εργασίας και ότι κάθε βοήθεια - την οποία είχα για την προετοιμασία της, είναι πλήρως - αναγνωρισμένη και αναφέρεται στην πτυχιακή εργασία. Επίσης έχω - αναφέρει τις όποιες πηγές από τις οποίες έκανα χρήση δεδομένων, - ιδεών ή λέξεων, είτε αυτές αναφέρονται ακριβώς είτε - παραφρασμένες. Επίσης βεβαιώνω ότι αυτή η πτυχιακή εργασία - προετοιμάστηκε από εμένα προσωπικά ειδικά για τις απαιτήσεις του - προγράμματος σπουδών του Τμήματος Μηχανικών Πληροφορικής ΤΕ του Τ.Ε.Ι. Κεντρικής Μακεδονίας. - } - {Βεβαιώνουμε ότι είμαστε συγγραφείς αυτής της πτυχιακής εργασίας και ότι κάθε βοήθεια - την οποία είχαμε για την προετοιμασία της, είναι πλήρως - αναγνωρισμένη και αναφέρεται στην πτυχιακή εργασία. Επίσης έχουμε - αναφέρει τις όποιες πηγές από τις οποίες κάναμε χρήση δεδομένων, - ιδεών ή λέξεων, είτε αυτές αναφέρονται ακριβώς είτε - παραφρασμένες. Επίσης βεβαιώνουμε ότι αυτή η πτυχιακή εργασία - προετοιμάστηκε από εμάς προσωπικά ειδικά για τις απαιτήσεις του - προγράμματος σπουδών του Τμήματος Μηχανικών Πληροφορικής ΤΕ του Τ.Ε.Ι. Κεντρικής Μακεδονίας.} - - \end{Declaration} -} -%********************************************************************** - - -% ******************************DEFINITIONS**************************** -\newcommand{\thesisdefinitions}{Ορισμοί} -\newcommand{\@thesisdefinitions}{\thesisdefinitions} - -\newenvironment{Definitions} -{ - \chapter*{\@thesisdefinitions - \@mkboth{}{}} - - \addcontentsline{toc}{chapter}{\@thesisdefinitions} - } -{} - -%********************************************************************** -%****************************Starting the main text!******************* -% The following code tries to fix ``running heads'' -% Running heads are not necessary but if they exist they should -% give the author's name with initials, year of submission and -% chapter number or heading -% First make it show the chapter number and heading -\renewcommand{\chaptermark}[1]{\markboth{\ - \thechapter. #1}{\ - \thechapter. #1}} -\renewcommand{\sectionmark}[1]{\markright{\thesection. #1}} - -% Now redefine myheadings to include all the relevant information -\newcommand{\Startpage}{\renewcommand{\ps@myheadings}{% - \renewcommand{\@oddhead}{\leftmark,\ - ~\thesisauthorabbrv,\thesisSecondAuthorabbrv\ - ~\thesisyear\hfil\thepage}% - \renewcommand{\@evenhead}{\@oddhead}% - \renewcommand{\@evenfoot}{}% empty - \renewcommand{\@oddfoot}{}% empty - } - \pagestyle{myheadings}} -%************************************************************************** - -%*******************************GLOSSARY******************************* -\newcommand{\thesisglossary}{Γλωσσάρι} -\newcommand{\@thesisglossary}{\thesisglossary} - -\newenvironment{Glossary} -{ - \chapter*{\@thesisglossary - \@mkboth{\thesisglossary}{\thesisglossary}} - - \addcontentsline{toc}{chapter}{\@thesisglossary} - } -{ } -%************************************************************************** - -%********************************************************************** -% Code shamelessly stolen follows now! - -% ******************************APPENDIX******************************* - -%% The following is taken from: csthesis.cls (Edinburgh University) -%% I changed the numbering to be arabic. -%% Redefine the appendix command to ensure that it does a pagebreak -%% (sorts problem of Appendix appearing in header of last page before -%% the first apppendix). -%% -%\renewcommand{\appendixname}{Παράρτημα} -\renewcommand{\appendix}{\vfill\pagebreak - \setcounter{chapter}{0}% - \setcounter{section}{0}% - \renewcommand\@chapapp{\appendixname}% - \renewcommand\chaptername{\appendixname}% - \renewcommand\thechapter{\@arabic\c@chapter} -} - -% -% ************************Table of contents**************************** -% -% The following code is taken from report.cls (c) LaTeX 3 Project -% I changed a little bit the definitions in order to produce running -% heads according to the BS standard -\renewcommand\tableofcontents{% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \chapter*{\contentsname - \@mkboth{% - \hfil\thepage}{\hfil\thepage}}% - \@starttoc{toc}% - \if@restonecol\twocolumn\fi - } -\renewcommand\listoffigures{% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \chapter*{\listfigurename - \@mkboth{\hfil\thepage}% - {\hfil\thepage}}% - \@starttoc{lof}% - \if@restonecol\twocolumn\fi - } -\renewcommand\listoftables{% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \chapter*{\listtablename - \@mkboth{% - \hfil\thepage}{\hfil\thepage}}% - \@starttoc{lot}% - \if@restonecol\twocolumn\fi - } -% ******************************REFERENCES***************************** - -%%% -%%% Command from report.cls, (c) LaTeX3 Project. -%%% -% \renewenvironment{thebibliography}[1] -% {\chapter*{\bibname -% \@mkboth{\bibname}{\bibname}}% -% \addcontentsline{toc}{chapter}{\bibname} -% \list{\@biblabel{\@arabic\c@enumiv}}% -% {\settowidth\labelwidth{\@biblabel{#1}}% -% \leftmargin\labelwidth -% \advance\leftmargin\labelsep -% \@openbib@code -% \usecounter{enumiv}% -% \let\p@enumiv\@empty -% \renewcommand\theenumiv{\@arabic\c@enumiv}}% -% \sloppy -% \clubpenalty4000 -% \@clubpenalty \clubpenalty -% \widowpenalty4000% -% \sfcode`\.\@m} -% {\def\@noitemerr -% {\@latex@warning{Empty `thebibliography' environment}}% -% \endlist} -\newcommand{\citep}[1]{\parencite{#1}} - -\newcommand{\lastpageinfo}{\newpage -\vspace*{\fill} -\thispagestyle{empty} -\scriptsize{\noindent Η εργασία αυτή στοιχειοθετήθηκε με το πρόγραμμα \XeLaTeX. Για τη στοιχειοθέτηση της βιβλιογραφίας χρησιμοποιήθηκε το πρόγραμμα \texttt{biber} και \texttt{biblatex}. Οι γραμματοσειρές που χρησιμοποιήθηκαν είναι οι Times New Roman και \texttt{Courier New}.} -} diff --git a/doc/thesis/thesis.tex b/doc/thesis/thesis.tex deleted file mode 100644 index 2685968c..00000000 --- a/doc/thesis/thesis.tex +++ /dev/null @@ -1,27 +0,0 @@ -%% ----------------------------------------------------------- -%% EASY!APPOINTMENTS THESIS -%% -%% STUDENT : ALEXANDROS TSELEGIDIS -%% INSTITUTION : TEI SERRON -%% DEPARTMENT : INFORMATION AND COMMUNICATION SCIENCE -%% DATE : NOVEMBER 2013 -%% -%% THIS FILE CONTAINS THE BSC THESIS FOR THE EASY!APPOINTMENTS -%% APPLICATION. THE DOCUMENT IS SPLIT INTO MULTIPLE FILES, IN -%% ORDER TO BE MORE FLEXIBLE AND EASY TO MAINTAIN. -%% ----------------------------------------------------------- -\input{includes/headers.tex} -\begin{document} - \input{includes/introduction.tex} - \input{includes/google-calendar-api.tex} - \input{includes/external-tools.tex} - \input{includes/usage-scenarios.tex} - \input{includes/use-cases.tex} - \input{includes/implementation.tex} - \input{includes/unit-testing.tex} - \input{includes/conclusions.tex} - \nocite{*} - \printbibliography - \lastpageinfo -\end{document} - \ No newline at end of file diff --git a/release-notes.txt b/release-notes.txt deleted file mode 100644 index e499a1b9..00000000 --- a/release-notes.txt +++ /dev/null @@ -1,20 +0,0 @@ -VERSION 1.0 -=========== -Easy!Appointments now supports multilingual interface (English, -German, Greek, Hungarian & Portuguese) - -I would like to thank Stefan Tselegidis (German), Zsolt Zala(Hungarian) and Andre Tavares (Portuguese) for their work on the translations. - - -Official Easy!Appointments Website: -http://easyappointments.org - -Check the Google+ Community for development updates: -https://plus.google.com/communities/105333709485142846840 - -Visit the Support Group for any help on the project: -http://groups.google.com/group/easy-appointments - -E!A Blog for news and information: -http://easyappointments.wordpress.com - \ No newline at end of file diff --git a/rsc/code-doc.sh b/rsc/code-doc.sh new file mode 100644 index 00000000..27225cb7 --- /dev/null +++ b/rsc/code-doc.sh @@ -0,0 +1,7 @@ +#!bin/bash + +# Generate PHP Documentation + + +# Generate JS Documentation (requires jsdoc) + diff --git a/rsc/db/sample-data.sql b/rsc/db/sample-data.sql new file mode 100644 index 00000000..a9196b4d --- /dev/null +++ b/rsc/db/sample-data.sql @@ -0,0 +1,103 @@ +-- phpMyAdmin SQL Dump +-- version 4.0.10deb1 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Jan 14, 2015 at 10:50 PM +-- Server version: 5.5.40-0ubuntu0.14.04.1 +-- PHP Version: 5.5.9-1ubuntu4.5 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- Database: `easyappointments` +-- + +-- +-- Dumping data for table `ea_roles` +-- + +INSERT INTO `ea_roles` (`id`, `name`, `slug`, `is_admin`, `appointments`, `customers`, `services`, `users`, `system_settings`, `user_settings`) VALUES +(1, 'Administrator', 'admin', 1, 15, 15, 15, 15, 15, 15), +(2, 'Provider', 'provider', 0, 15, 15, 0, 0, 0, 15), +(3, 'Customer', 'customer', 0, 0, 0, 0, 0, 0, 0), +(4, 'Secretary', 'secretary', 0, 15, 15, 0, 0, 0, 15); + +-- +-- Dumping data for table `ea_secretaries_providers` +-- + +INSERT INTO `ea_secretaries_providers` (`id_users_secretary`, `id_users_provider`) VALUES +(87, 86); + +-- +-- Dumping data for table `ea_services` +-- + +INSERT INTO `ea_services` (`id`, `name`, `duration`, `price`, `currency`, `description`, `id_service_categories`) VALUES +(1, 'Best Quick Service ', 30, 50.00, '€', 'This is the best service and it requires only 30 minutes of your time!', 1), +(2, 'Another Q. Service', 45, 60.00, '€', 'This will be the best choice for someone that wants a balance between time and money.', 1), +(3, 'Best Long Service', 180, 100.00, '€', 'This long service will examine all the aspects of your problem. Definitely the best solution!', 2), +(4, 'Ungrouped Srv.', 45, 0.00, '', 'This category is not like the rest. It can''t be grouped. ', NULL); + +-- +-- Dumping data for table `ea_services_providers` +-- + +INSERT INTO `ea_services_providers` (`id_users`, `id_services`) VALUES +(85, 1), +(85, 2), +(86, 3), +(85, 4), +(86, 4); + +-- +-- Dumping data for table `ea_service_categories` +-- + +INSERT INTO `ea_service_categories` (`id`, `name`, `description`) VALUES +(1, 'Quick Services', 'A collection of services that have small duration. '), +(2, 'Long Services', 'A collection of services that require more time. '); + +-- +-- Dumping data for table `ea_settings` +-- + +INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES +(16, 'company_working_plan', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"saturday":null,"sunday":null}'), +(17, 'book_advance_timeout', '30'), +(18, 'company_name', 'ABC Company'), +(19, 'company_email', 'info@abc-company.ea'), +(20, 'company_link', 'http://www.abc-company.ea'); + +-- +-- Dumping data for table `ea_users` +-- + +INSERT INTO `ea_users` (`id`, `first_name`, `last_name`, `email`, `mobile_number`, `phone_number`, `address`, `city`, `state`, `zip_code`, `notes`, `id_roles`) VALUES +(84, 'John', 'Smith', 'info@abc-company.ea', '0123 4567890', '0123 4567891', 'Tst-Address 12', 'Tst-City', 'Tst-State', '012345', 'Test administrator record for this installation. ', 1), +(85, 'George ', 'Clayton', 'g.clayton@abc-company.ea', '0123 456 7890', '0123 456 7891', 'Tst-Address 12', 'Tst-City', 'Tst-State', '012345', 'This is one of the test providers. He will handle the quick services.', 2), +(86, 'Christina', 'Nickolson', 'c.nickolson@abc-company.ea', '0123 4567890', '0123 4567891', 'Tst-Address 12', 'Tst-City', 'Tst-State', '012345', 'This provider will handle the long services.', 2), +(87, 'Nicky', 'Rowland', 'n.rowland@abc-company.ea', '0123 4567890', '0123 4567891', 'Tst-Address 12', 'Tst-City', 'Tst-State', '012345', 'This is the only secretary of the app. She will handle the data of Christina.', 4), +(88, 'John', 'Doe', 'john.doe@abc-company.ea', NULL, '0123 4567890', 'Tst-Address 12', 'Tst-City', NULL, '012345', 'This is a test customer record.', 3); + +-- +-- Dumping data for table `ea_user_settings` +-- + +INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `salt`, `working_plan`, `notifications`, `google_sync`, `google_token`, `google_calendar`, `sync_past_days`, `sync_future_days`) VALUES +(84, 'administrator', 'fa7fc34500cbed7c3546f8b223f10797f24ecc9ccbf0c2251c21ab965ebf19bf', 'e0a9e47fbf57babcf536e98bed783a9404b95b671cdcf9e391f68989fa3ac14f', NULL, 1, 0, NULL, NULL, 5, 5), +(85, 'g.clayton', 'a86f0c41be938c36eaedb3c4869c445fe8b7192188110f57bf86b55ac2252f05', '9b56eaa06cb0cc1c3bdce616291da4f53c2cc5d3449591bacb28099346333f05', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"saturday":null,"sunday":null}', 1, 0, NULL, NULL, 5, 5), +(86, 'c.nickolson', '7dcd5ed6a1cc42de678227aa8d528069761b218d181ff7ef446a49622c384782', '807349d6bacc35650205c66d664d4d414d150dec7f17dbba360752224bab73f4', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"14:30","end":"15:00"}]},"saturday":null,"sunday":null}', 1, 0, NULL, NULL, 5, 5), +(87, 'n.rowland', '8cd1cc276a72f88e6d27372aecde8d87903a91fa33a6d2aceafbf2d110e4c9c2', '55b3a83cea1e3a5c4945fcb12a7621519705b3d09c4fa3408d912a832c8410a1', NULL, 1, 0, NULL, NULL, 5, 5); + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/rsc/db/structure.sql b/rsc/db/structure.sql new file mode 100644 index 00000000..5db77ad7 --- /dev/null +++ b/rsc/db/structure.sql @@ -0,0 +1,220 @@ + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- Database: `easyappointments` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_appointments` +-- + +CREATE TABLE IF NOT EXISTS `ea_appointments` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `book_datetime` datetime DEFAULT NULL, + `start_datetime` datetime DEFAULT NULL, + `end_datetime` datetime DEFAULT NULL, + `notes` text, + `hash` text, + `is_unavailable` tinyint(4) DEFAULT '0', + `id_users_provider` bigint(20) unsigned DEFAULT NULL, + `id_users_customer` bigint(20) unsigned DEFAULT NULL, + `id_services` bigint(20) unsigned DEFAULT NULL, + `id_google_calendar` text, + PRIMARY KEY (`id`), + KEY `id_users_customer` (`id_users_customer`), + KEY `id_services` (`id_services`), + KEY `id_users_provider` (`id_users_provider`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_roles` +-- + +CREATE TABLE IF NOT EXISTS `ea_roles` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) DEFAULT NULL, + `slug` varchar(256) DEFAULT NULL, + `is_admin` tinyint(4) DEFAULT NULL COMMENT '0', + `appointments` int(4) DEFAULT NULL COMMENT '0', + `customers` int(4) DEFAULT NULL COMMENT '0', + `services` int(4) DEFAULT NULL COMMENT '0', + `users` int(4) DEFAULT NULL COMMENT '0', + `system_settings` int(4) DEFAULT NULL COMMENT '0', + `user_settings` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_secretaries_providers` +-- + +CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` ( + `id_users_secretary` bigint(20) unsigned NOT NULL, + `id_users_provider` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id_users_secretary`,`id_users_provider`), + KEY `fk_ea_secretaries_providers_1` (`id_users_secretary`), + KEY `fk_ea_secretaries_providers_2` (`id_users_provider`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_services` +-- + +CREATE TABLE IF NOT EXISTS `ea_services` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) DEFAULT NULL, + `duration` int(11) DEFAULT NULL, + `price` decimal(10,2) DEFAULT NULL, + `currency` varchar(32) DEFAULT NULL, + `description` text, + `id_service_categories` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `id_service_categories` (`id_service_categories`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_services_providers` +-- + +CREATE TABLE IF NOT EXISTS `ea_services_providers` ( + `id_users` bigint(20) unsigned NOT NULL, + `id_services` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id_users`,`id_services`), + KEY `id_services` (`id_services`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_service_categories` +-- + +CREATE TABLE IF NOT EXISTS `ea_service_categories` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(256) DEFAULT NULL, + `description` text, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_settings` +-- + +CREATE TABLE IF NOT EXISTS `ea_settings` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(512) DEFAULT NULL, + `value` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_users` +-- + +CREATE TABLE IF NOT EXISTS `ea_users` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(256) DEFAULT NULL, + `last_name` varchar(512) DEFAULT NULL, + `email` varchar(512) DEFAULT NULL, + `mobile_number` varchar(128) DEFAULT NULL, + `phone_number` varchar(128) DEFAULT NULL, + `address` varchar(256) DEFAULT NULL, + `city` varchar(256) DEFAULT NULL, + `state` varchar(128) DEFAULT NULL, + `zip_code` varchar(64) DEFAULT NULL, + `notes` text, + `id_roles` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `id_roles` (`id_roles`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=85 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ea_user_settings` +-- + +CREATE TABLE IF NOT EXISTS `ea_user_settings` ( + `id_users` bigint(20) unsigned NOT NULL, + `username` varchar(256) DEFAULT NULL, + `password` varchar(512) DEFAULT NULL, + `salt` varchar(512) DEFAULT NULL, + `working_plan` text, + `notifications` tinyint(4) DEFAULT '0', + `google_sync` tinyint(4) DEFAULT '0', + `google_token` text, + `google_calendar` varchar(128) DEFAULT NULL, + `sync_past_days` int(11) DEFAULT '5', + `sync_future_days` int(11) DEFAULT '5', + PRIMARY KEY (`id_users`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `ea_appointments` +-- +ALTER TABLE `ea_appointments` + ADD CONSTRAINT `ea_appointments_ibfk_2` FOREIGN KEY (`id_users_customer`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `ea_appointments_ibfk_3` FOREIGN KEY (`id_services`) REFERENCES `ea_services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `ea_appointments_ibfk_4` FOREIGN KEY (`id_users_provider`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- +-- Constraints for table `ea_secretaries_providers` +-- +ALTER TABLE `ea_secretaries_providers` + ADD CONSTRAINT `fk_ea_secretaries_providers_1` FOREIGN KEY (`id_users_secretary`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `fk_ea_secretaries_providers_2` FOREIGN KEY (`id_users_provider`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- +-- Constraints for table `ea_services` +-- +ALTER TABLE `ea_services` + ADD CONSTRAINT `ea_services_ibfk_1` FOREIGN KEY (`id_service_categories`) REFERENCES `ea_service_categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- +-- Constraints for table `ea_services_providers` +-- +ALTER TABLE `ea_services_providers` + ADD CONSTRAINT `ea_services_providers_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `ea_services_providers_ibfk_2` FOREIGN KEY (`id_services`) REFERENCES `ea_services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- +-- Constraints for table `ea_users` +-- +ALTER TABLE `ea_users` + ADD CONSTRAINT `ea_users_ibfk_1` FOREIGN KEY (`id_roles`) REFERENCES `ea_roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- +-- Constraints for table `ea_user_settings` +-- +ALTER TABLE `ea_user_settings` + ADD CONSTRAINT `ea_user_settings_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/rsc/design/logo/ea-logo.png b/rsc/gfx/logo/ea-logo.png similarity index 100% rename from rsc/design/logo/ea-logo.png rename to rsc/gfx/logo/ea-logo.png diff --git a/rsc/design/logo/ea-logo.psd b/rsc/gfx/logo/ea-logo.psd similarity index 100% rename from rsc/design/logo/ea-logo.psd rename to rsc/gfx/logo/ea-logo.psd diff --git a/rsc/design/logo/gplus-ea-logo.png b/rsc/gfx/logo/gplus-ea-logo.png similarity index 100% rename from rsc/design/logo/gplus-ea-logo.png rename to rsc/gfx/logo/gplus-ea-logo.png diff --git a/rsc/design/logo/installation-banner.png b/rsc/gfx/logo/installation-banner.png similarity index 100% rename from rsc/design/logo/installation-banner.png rename to rsc/gfx/logo/installation-banner.png diff --git a/rsc/design/logo/installation-banner.psd b/rsc/gfx/logo/installation-banner.psd similarity index 100% rename from rsc/design/logo/installation-banner.psd rename to rsc/gfx/logo/installation-banner.psd diff --git a/rsc/design/misc/google-code-banner.png b/rsc/gfx/misc/google-code-banner.png similarity index 100% rename from rsc/design/misc/google-code-banner.png rename to rsc/gfx/misc/google-code-banner.png diff --git a/rsc/design/misc/google-code-banner.psd b/rsc/gfx/misc/google-code-banner.psd similarity index 100% rename from rsc/design/misc/google-code-banner.psd rename to rsc/gfx/misc/google-code-banner.psd diff --git a/rsc/misc/code/CodeIgniter_2.1.3.zip b/rsc/misc/code/CodeIgniter_2.1.3.zip deleted file mode 100644 index 2b301c97..00000000 Binary files a/rsc/misc/code/CodeIgniter_2.1.3.zip and /dev/null differ diff --git a/rsc/misc/ebooks/RUP pt1.pdf b/rsc/misc/ebooks/RUP pt1.pdf deleted file mode 100644 index 96ca836d..00000000 Binary files a/rsc/misc/ebooks/RUP pt1.pdf and /dev/null differ diff --git a/rsc/misc/ebooks/RUP pt2.pdf b/rsc/misc/ebooks/RUP pt2.pdf deleted file mode 100644 index c5c4b871..00000000 Binary files a/rsc/misc/ebooks/RUP pt2.pdf and /dev/null differ diff --git a/rsc/misc/ebooks/RUP pt3.pdf b/rsc/misc/ebooks/RUP pt3.pdf deleted file mode 100644 index 193a09ff..00000000 Binary files a/rsc/misc/ebooks/RUP pt3.pdf and /dev/null differ diff --git a/rsc/misc/ebooks/listings.pdf b/rsc/misc/ebooks/listings.pdf deleted file mode 100644 index 2e8f263b..00000000 Binary files a/rsc/misc/ebooks/listings.pdf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/Apache License Version 2.txt b/rsc/misc/fonts/open sans/Apache License Version 2.txt deleted file mode 100644 index e395039f..00000000 --- a/rsc/misc/fonts/open sans/Apache License Version 2.txt +++ /dev/null @@ -1,53 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -&quot;License&quot; shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -&quot;Licensor&quot; shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -&quot;Legal Entity&quot; shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, &quot;control&quot; means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -&quot;You&quot; (or &quot;Your&quot;) shall mean an individual or Legal Entity exercising permissions granted by this License. - -&quot;Source&quot; form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -&quot;Object&quot; form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -&quot;Work&quot; shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -&quot;Derivative Works&quot; shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -&quot;Contribution&quot; shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, &quot;submitted&quot; means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as &quot;Not a Contribution.&quot; - -&quot;Contributor&quot; shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a &quot;NOTICE&quot; text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. \ No newline at end of file diff --git a/rsc/misc/fonts/open sans/OpenSans-Bold.ttf b/rsc/misc/fonts/open sans/OpenSans-Bold.ttf deleted file mode 100644 index fd79d43b..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-Bold.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-BoldItalic.ttf b/rsc/misc/fonts/open sans/OpenSans-BoldItalic.ttf deleted file mode 100644 index 9bc80095..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-BoldItalic.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-ExtraBold.ttf b/rsc/misc/fonts/open sans/OpenSans-ExtraBold.ttf deleted file mode 100644 index 21f6f84a..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-ExtraBoldItalic.ttf b/rsc/misc/fonts/open sans/OpenSans-ExtraBoldItalic.ttf deleted file mode 100644 index 31cb6883..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-ExtraBoldItalic.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-Italic.ttf b/rsc/misc/fonts/open sans/OpenSans-Italic.ttf deleted file mode 100644 index c90da48f..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-Italic.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-Light.ttf b/rsc/misc/fonts/open sans/OpenSans-Light.ttf deleted file mode 100644 index 0d381897..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-Light.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-LightItalic.ttf b/rsc/misc/fonts/open sans/OpenSans-LightItalic.ttf deleted file mode 100644 index 68299c4b..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-LightItalic.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-Regular.ttf b/rsc/misc/fonts/open sans/OpenSans-Regular.ttf deleted file mode 100644 index db433349..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-Regular.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-Semibold.ttf b/rsc/misc/fonts/open sans/OpenSans-Semibold.ttf deleted file mode 100644 index 1a7679e3..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-Semibold.ttf and /dev/null differ diff --git a/rsc/misc/fonts/open sans/OpenSans-SemiboldItalic.ttf b/rsc/misc/fonts/open sans/OpenSans-SemiboldItalic.ttf deleted file mode 100644 index 59b6d16b..00000000 Binary files a/rsc/misc/fonts/open sans/OpenSans-SemiboldItalic.ttf and /dev/null differ diff --git a/rsc/package.sh b/rsc/package.sh new file mode 100644 index 00000000..579e4c7f --- /dev/null +++ b/rsc/package.sh @@ -0,0 +1,10 @@ +#!bin/bash + + +# Create Build Directory + + +# Minify and Concatenate Assets Code + + +# Zip Folder \ No newline at end of file diff --git a/rsc/scripts/jsdoc/Jake/lib/mustache.js b/rsc/scripts/jsdoc/Jake/lib/mustache.js deleted file mode 100644 index 60687a38..00000000 --- a/rsc/scripts/jsdoc/Jake/lib/mustache.js +++ /dev/null @@ -1,335 +0,0 @@ -/* - mustache.js — Logic-less templates in JavaScript - - See http://mustache.github.com/ for more info. -*/ - -var Mustache = function() { - var Renderer = function() {}; - - Renderer.prototype = { - otag: "{{", - ctag: "}}", - pragmas: {}, - buffer: [], - pragmas_implemented: { - "IMPLICIT-ITERATOR": true, - "ARRAY-ORDINALS": true // define #first? and #last? when looping arrays - }, - context: {}, - - render: function(template, context, partials, in_recursion) { - // reset buffer & set context - if(!in_recursion) { - this.context = context; - this.buffer = []; // TODO: make this non-lazy - } - - // fail fast - if(!this.includes("", template)) { - if(in_recursion) { - return template; - } else { - this.send(template); - return; - } - } - - template = this.render_pragmas(template); - var html = this.render_section(template, context, partials); - if(in_recursion) { - return this.render_tags(html, context, partials, in_recursion); - } - - this.render_tags(html, context, partials, in_recursion); - }, - - /* - Sends parsed lines - */ - send: function(line) { - if(line != "") { - this.buffer.push(line); - } - }, - - /* - Looks for %PRAGMAS - */ - render_pragmas: function(template) { - // no pragmas - if(!this.includes("%", template)) { - return template; - } - - var that = this; - var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + - this.ctag); - return template.replace(regex, function(match, pragma, options) { - if(!that.pragmas_implemented[pragma]) { - throw({message: - "This implementation of mustache doesn't understand the '" + - pragma + "' pragma"}); - } - that.pragmas[pragma] = {}; - if(options) { - var opts = options.split("="); - that.pragmas[pragma][opts[0]] = opts[1]; - } - return ""; - // ignore unknown pragmas silently - }); - }, - - /* - Tries to find a partial in the curent scope and render it - */ - render_partial: function(name, context, partials) { - name = this.trim(name); - if(!partials || partials[name] === undefined) { - throw({message: "unknown_partial '" + name + "'"}); - } - if(typeof(context[name]) != "object") { - return this.render(partials[name], context, partials, true); - } - return this.render(partials[name], context[name], partials, true); - }, - - /* - Renders inverted (^) and normal (#) sections - */ - render_section: function(template, context, partials) { - if(!this.includes("#", template) && !this.includes("^", template)) { - return template; - } - - var that = this; - // CSW - Added "+?" so it finds the tighest bound, not the widest - var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag + - "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag + - "\\s*", "mg"); - - // for each {{#foo}}{{/foo}} section do... - return template.replace(regex, function(match, type, name, content) { - var value = that.find(name, context); - if(type == "^") { // inverted section - if(!value || that.is_array(value) && value.length === 0) { - // false or empty list, render it - return that.render(content, context, partials, true); - } else { - return ""; - } - } else if(type == "#") { // normal section - if(that.is_array(value)) { // Enumerable, Let's loop! - var len = value.length; - return value.map(function(row, i) { - return that.render(content, that.create_context(row, {first: i === 0, last: i === len-1}), - partials, true); - }).join(""); - } else if(that.is_object(value)) { // Object, Use it as subcontext! - return that.render(content, that.create_context(value), - partials, true); - } else if(typeof value === "function") { - // higher order section - return value.call(context, content, function(text) { - return that.render(text, context, partials, true); - }); - } else if(value) { // boolean section - return that.render(content, context, partials, true); - } else { - return ""; - } - } - }); - }, - - /* - Replace {{foo}} and friends with values from our view - */ - render_tags: function(template, context, partials, in_recursion) { - // tit for tat - var that = this; - - var new_regex = function() { - return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" + - that.ctag + "+", "g"); - }; - - var regex = new_regex(); - var tag_replace_callback = function(match, operator, name) { - switch(operator) { - case "!": // ignore comments - return ""; - case "=": // set new delimiters, rebuild the replace regexp - that.set_delimiters(name); - regex = new_regex(); - return ""; - case ">": // render partial - return that.render_partial(name, context, partials); - case "{": // the triple mustache is unescaped - return that.find(name, context); - default: // escape the value - return that.escape(that.find(name, context)); - } - }; - var lines = template.split("\n"); - for(var i = 0; i < lines.length; i++) { - lines[i] = lines[i].replace(regex, tag_replace_callback, this); - if(!in_recursion) { - this.send(lines[i]); - } - } - - if(in_recursion) { - return lines.join("\n"); - } - }, - - set_delimiters: function(delimiters) { - var dels = delimiters.split(" "); - this.otag = this.escape_regex(dels[0]); - this.ctag = this.escape_regex(dels[1]); - }, - - escape_regex: function(text) { - // thank you Simon Willison - if(!arguments.callee.sRE) { - var specials = [ - '/', '.', '*', '+', '?', '|', - '(', ')', '[', ']', '{', '}', '\\' - ]; - arguments.callee.sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - } - return text.replace(arguments.callee.sRE, '\\$1'); - }, - - /* - find `name` in current `context`. That is find me a value - from the view object - */ - find: function(name, context) { - name = this.trim(name); - - // Checks whether a value is thruthy or false or 0 - function is_kinda_truthy(bool) { - return bool === false || bool === 0 || bool; - } - - var value; - if(is_kinda_truthy(context[name])) { - value = context[name]; - } else if(is_kinda_truthy(this.context[name])) { - value = this.context[name]; - } - - if(typeof value === "function") { - return value.apply(context); - } - if(value !== undefined) { - return value; - } - // silently ignore unkown variables - return ""; - }, - - // Utility methods - - /* includes tag */ - includes: function(needle, haystack) { - return haystack.indexOf(this.otag + needle) != -1; - }, - - /* - Does away with nasty characters - */ - escape: function(s) { - s = String(s === null ? "" : s); - return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) { - switch(s) { - case "&": return "&"; - case "\\": return "\\\\"; - case '"': return '"'; - case "'": return '''; - case "<": return "<"; - case ">": return ">"; - default: return s; - } - }); - }, - - // by @langalex, support for arrays of strings - create_context: function(_context, opts) { - if(this.is_object(_context)) { - if (this.pragmas["ARRAY-ORDINALS"] && opts) { - _context['first?'] = opts.first || false; - _context['last?'] = opts.last || false; - } - return _context; - } else { - var iterator = "."; - if(this.pragmas["IMPLICIT-ITERATOR"]) { - iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; - } - var ctx = {}; - ctx[iterator] = _context; - if (this.pragmas["ARRAY-ORDINALS"] && opts){ - ctx['first?'] = opts.first || false; - ctx['last?'] = opts.last || false; - } - return ctx; - } - }, - - is_object: function(a) { - return a && typeof a == "object"; - }, - - is_array: function(a) { - return Object.prototype.toString.call(a) === '[object Array]'; - }, - - /* - Gets rid of leading and trailing whitespace - */ - trim: function(s) { - return s.replace(/^\s*|\s*$/g, ""); - }, - - /* - Why, why, why? Because IE. Cry, cry cry. - */ - map: function(array, fn) { - if (typeof array.map == "function") { - return array.map(fn); - } else { - var r = []; - var l = array.length; - for(var i = 0; i < l; i++) { - r.push(fn(array[i])); - } - return r; - } - } - }; - - return({ - name: "mustache.js", - version: "0.3.1-dev", - - /* - Turns a template and view into HTML - */ - to_html: function(template, view, partials, send_fun) { - var renderer = new Renderer(); - if(send_fun) { - renderer.send = send_fun; - } - renderer.render(template, view, partials); - if(!send_fun) { - return renderer.buffer.join("\n"); - } - } - }); -}(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/Jake/templates/package.json.tmpl b/rsc/scripts/jsdoc/Jake/templates/package.json.tmpl deleted file mode 100644 index d5159473..00000000 --- a/rsc/scripts/jsdoc/Jake/templates/package.json.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "{{appname}}", - "version": "{{appversion}}", - "revision": "{{timestamp}}", - "description": "An API documentation generator for JavaScript.", - "keywords": [ "documentation", "javascript" ], - "licenses": [ - { - "type": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "repositories": [ - { - "type": "git", - "url": "https://github.com/jsdoc3/jsdoc" - } - ], - "dependencies": { - "async": "0.1.22", - "catharsis": "0.5.6", - "crypto-browserify": "git+https://github.com/dominictarr/crypto-browserify.git#95c5d505", - "js2xmlparser": "0.1.0", - "jshint": "0.9.1", - "markdown": "git+https://github.com/jsdoc3/markdown-js.git", - "marked": "0.2.8", - "taffydb": "git+https://github.com/hegemonic/taffydb.git", - "underscore": "1.4.2", - "wrench": "1.3.9" - }, - "bin": "./nodejs/bin/jsdoc", - "bugs": "https://github.com/jsdoc3/jsdoc/issues", - "author": { - "name": "Michael Mathews", - "email": "micmath@gmail.com" - }, - "contributors": [ - { - "url": "https://github.com/jsdoc3/jsdoc/graphs/contributors" - } - ], - "maintainers": { - "name": "Jeff Williams", - "email": "jeffrey.l.williams@gmail.com" - } -} diff --git a/rsc/scripts/jsdoc/Jakefile.js b/rsc/scripts/jsdoc/Jakefile.js deleted file mode 100644 index 751dd54e..00000000 --- a/rsc/scripts/jsdoc/Jakefile.js +++ /dev/null @@ -1,82 +0,0 @@ -/*global desc: true, fail: true, Mustache: true, task: true */ -// see: https://github.com/mde/jake - -desc('Updating package.json revision.'); -task('default', [], function(params) { - /*jshint evil: true */ - var fs = require('fs'); - - // import the Mustache template tool - eval(fs.readFileSync('Jake/lib/mustache.js', 'utf8')); - - var templates = { - packagejson : fs.readFileSync('Jake/templates/package.json.tmpl', 'utf8') - }; - - var metadata = { - appname : 'jsdoc', - appversion : '3.2.0-dev', - timestamp : '' + new Date().getTime() - }; - - var outdir = './'; - - var rendered = Mustache.to_html(templates.packagejson, metadata); - - fs.writeFileSync(outdir + 'package.json', rendered, 'utf8'); - - process.exit(0); - -}); - -desc('Installs a plugin/template.'); -task('install', [], function(loc) { - var fs = require('fs'), - util = require('util'), - path = require('path'), - wrench = require('wrench'); - - if(!loc) { - fail("You must specify the location of the plugin/template."); - } - - if(!fs.existsSync(loc)) { - fail("plugin/template location [" + loc + "] is not valid."); - } - - var pluginLoc = path.join(loc, "plugins"), - templateLoc = path.join(loc, "templates"), - jsdocLoc = process.cwd(), - name, - config; - - //First the plugin - if(fs.existsSync(pluginLoc)) { - //copy it over - wrench.copyDirSyncRecursive(pluginLoc, path.join(jsdocLoc, "plugins"), { - preserve : true - }); - //find out what it's called - name = fs.readdirSync(pluginLoc)[0].replace(".js", ""); - //And finally edit the conf.json - try { - config = JSON.parse(fs.readFileSync(path.join(jsdocLoc, 'conf.json'), 'utf8')); - if(config.plugins.indexOf('plugins/' + name) == -1) { - config.plugins.push('plugins/' + name); - fs.writeFileSync(path.join(jsdocLoc, 'conf.json'), JSON.stringify(config, null, " "), 'utf8'); - } - } catch (e) { - fail("Could not edit the conf.json file: " + e); - } - } - - //Then the template - if(fs.existsSync(templateLoc)) { - wrench.copyDirSyncRecursive(templateLoc, path.join(jsdocLoc, "templates"), { - preserve : true - }); - } - - process.exit(0); - -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/LICENSE.md b/rsc/scripts/jsdoc/LICENSE.md deleted file mode 100644 index e06fb138..00000000 --- a/rsc/scripts/jsdoc/LICENSE.md +++ /dev/null @@ -1,344 +0,0 @@ -# License # - -JSDoc 3 is free software, licensed under the Apache License, Version 2.0 (the -"License"). Commercial and non-commercial use are permitted in compliance with -the License. - -Copyright (c) 2011-2012 Michael Mathews -All rights reserved. - -You may obtain a copy of the License at: -http://www.apache.org/licenses/LICENSE-2.0 - -In addition, a copy of the License is included with this distribution. - -As stated in Section 7, "Disclaimer of Warranty," of the License: - -> Licensor provides the Work (and each Contributor provides its Contributions) -> on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -> express or implied, including, without limitation, any warranties or -> conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -> PARTICULAR PURPOSE. You are solely responsible for determining the -> appropriateness of using or redistributing the Work and assume any risks -> associated with Your exercise of mpermissions under this License. - -The source code for JSDoc 3 is available at: -https://github.com/jsdoc3/jsdoc - - -# Third-Party Software # - -JSDoc 3 includes or depends upon the following third-party software, either in -whole or in part. Each third-party software package is provided under its own -license. - -## MIT License ## - -Several of the following software packages are distributed under the MIT -license, which is reproduced below: - -> 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. - - -## Async.js ## - -Async.js is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2010 Caolan McMahon. - -The source code for Async.js is available at: -https://github.com/caolan/async - - -## Catharsis ## - -Catharsis is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2012-2013 Jeff Williams. - -The source code for Catharsis is available at: -https://github.com/hegemonic/catharsis - - -## crypto-browserify ## - -License information for crypto-browserify is not available. It is assumed that -the package is distributed under the MIT license or a similar open source -license. - -The source code for crypto-browserify is available at: -https://github.com/dominictarr/crypto-browserify - - -## github-flavored-markdown ## - -github-flavored-markdown is distributed under the BSD 3-clause license: - -> Copyright (c) 2007, John Fraser All rights -> reserved. -> -> Original Markdown copyright (c) 2004, John Gruber -> All rights reserved. -> -> Redistribution and use in source and binary forms, with or without -> modification, are permitted provided that the following conditions are met: -> -> - Redistributions of source code must retain the above copyright notice, -> this list of conditions and the following disclaimer. -> -> - Redistributions in binary form must reproduce the above copyright notice, -> this list of conditions and the following disclaimer in the documentation -> and/or other materials provided with the distribution. - -> - Neither the name "Markdown" nor the names of its contributors may be used -> to endorse or promote products derived from this software without specific -> prior written permission. -> -> This software is provided by the copyright holders and contributors "as is" -> and any express or implied warranties, including, but not limited to, the -> implied warranties of merchantability and fitness for a particular purpose are -> disclaimed. In no event shall the copyright owner or contributors be liable -> for any direct, indirect, incidental, special, exemplary, or consequential -> damages (including, but not limited to, procurement of substitute goods or -> services; loss of use, data, or profits; or business interruption) however -> caused and on any theory of liability, whether in contract, strict liability, -> or tort (including negligence or otherwise) arising in any way out of the use -> of this software, even if advised of the possibility of such damage. - -The source code for github-flavored-markdown is available at: -https://github.com/hegemonic/github-flavored-markdown - - -## Google Code Prettify ## - -Google Code Prettify is distributed under the Apache License 2.0, which is -included with this package. - -Copyright (c) 2006 Google Inc. - -The source code for Google Code Prettify is available at: -https://code.google.com/p/google-code-prettify/ - - -## Jasmine ## - -Jasmine is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2008-2011 Pivotal Labs. - -The source code for Jasmine is available at: -https://github.com/pivotal/jasmine - - -## jasmine-node ## - -jasmine-node is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2010 Adam Abrons and Misko Hevery (http://getangular.com). - -The source code for jasmine-node is available at: -https://github.com/mhevery/jasmine-node - - -## js2xmlparser ## - -js2xmlparser is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2012 Michael Kourlas. - -The source code for js2xmlparser is available at: -https://github.com/michaelkourlas/node-js2xmlparser - - -## JSHint ## - -JSHint is distributed under the MIT license, which is reproduced above. - -Portions of JSHint are derived from JSLint, which is distributed under a -modified MIT license: - -> Copyright (c) 2002 Douglas Crockford (www.JSLint.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 shall be used for Good, not Evil. -> -> 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. - -The source code for JSHint is available at: -https://github.com/jshint/jshint - - -## markdown-js ## - -markdown-js is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2009-2010 Dominic Baggott. Copyright (c) 2009-2010 Ash Berlin. -Copyright (c) 2011 Christoph Dorn -(http://www.christophdorn.com). - -The source code for markdown-js is available at: -https://github.com/evilstreak/markdown-js - - -## Node.js ## - -Portions of the Node.js source code are incorporated into the following files: - -- `rhino/fs.js` -- `rhino/path.js` -- `rhino/querystring.js` -- `rhino/util.js` - -Node.js is distributed under the MIT license, which is reproduced above. - -Copyright Joyent, Inc. and other Node contributors. All rights reserved. - -The source code for Node.js is available at: -https://github.com/joyent/node - - -## node-browserify ## - -Portions of the node-browserify source code are incorporated into the following -files: - -- `rhino/events.js` - -node-browserify is distributed under the MIT license, which is reproduced above. - -The source code for node-browserify is available at: -https://github.com/substack/node-browserify - - -## TaffyDB ## - -TaffyDB is distributed under a modified BSD license: - -> All rights reserved. -> -> Redistribution and use of this software in source and binary forms, with or -> without modification, are permitted provided that the following condition is -> met: -> -> Redistributions of source code must retain the above copyright notice, this -> list of conditions and the following disclaimer. -> -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -> ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -> LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -> CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -> SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -> INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -> CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -> ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -> POSSIBILITY OF SUCH DAMAGE. - -The source code for TaffyDB is available at: -https://github.com/hegemonic/taffydb - - -## Tomorrow Theme for Google Code Prettify ## - -License information for the Tomorrow Theme for Google Code Prettify is not -available. It is assumed that the package is distributed under an open source -license that is compatible with the Apache License 2.0. - -Copyright (c) Yoshihide Jimbo. - -The source code for the Tomorrow Theme is available at: -https://github.com/jmblog/color-themes-for-google-code-prettify - - -## Rhino ## - -Rhino is distributed under the following licenses: - -### MPL/GPL License ### -The majority of the source code for Rhino is available under a MPL 1.1/GPL 2.0 -license. JSDoc 3 uses the source code under the MPL 1.1 license, which is -included in this distribution. - -### License for portions of the Rhino debugger ### -Additionally, some files are available under the BSD 3-clause license: - -> Copyright 1997, 1998 Sun Microsystems, Inc. All Rights Reserved. -> -> Redistribution and use in source and binary forms, with or without -> modification, are permitted provided that the following conditions are met: -> -> - Redistributions of source code must retain the above copyright notice, -> this list of conditions and the following disclaimer. -> - Redistributions in binary form must reproduce the above copyright -> notice, this list of conditions and the following disclaimer in the -> documentation and/or other materials provided with the distribution. -> - Neither the name of Sun Microsystems nor the names of its contributors -> may be used to endorse or promote products derived from this software -> without specific prior written permission. -> -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -### Source Code ### -The source code for Rhino is available at: -https://github.com/hegemonic/rhino - - -## Underscore.js ## - -Underscore.js is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud. - -The source code for Underscore.js is available at: -https://github.com/documentcloud/underscore - - -## wrench-js ## - -wrench-js is distributed under the MIT license, which is reproduced above. - -Copyright (c) 2010 Ryan McGrath. - -The source code for wrench-js is available at: -https://github.com/ryanmcgrath/wrench-js diff --git a/rsc/scripts/jsdoc/README.md b/rsc/scripts/jsdoc/README.md deleted file mode 100644 index c4a05467..00000000 --- a/rsc/scripts/jsdoc/README.md +++ /dev/null @@ -1,116 +0,0 @@ -JSDoc 3 -======= -[![Build Status](https://secure.travis-ci.org/jsdoc3/jsdoc.png?branch=master)](http://travis-ci.org/jsdoc3/jsdoc) - -An inline API documentation processor for JavaScript. JSDoc 3 is intended to be -an upgrade to JsDoc Toolkit (JSDoc 2). - -Want to contribute to JSDoc? Please read `CONTRIBUTING.md`. - - -Installation ------------- - -Use git to clone the [official JSDoc repository](https://github.com/jsdoc3/jsdoc): - - git clone git@github.com:jsdoc3/jsdoc.git - -Alternatively, you can download a .zip file for the -[latest development version](https://github.com/jsdoc3/jsdoc/archive/master.zip) -or a [previous release](https://github.com/jsdoc3/jsdoc/tags). - -You can also install JSDoc within a Node.js project's `node_modules` directory -using npm. To install the latest development version, change directories to your -Node.js project, then run the following command: - - npm install git://github.com/jsdoc3/jsdoc.git - -Or to install JSDoc globally: - - npm install -g git://github.com/jsdoc3/jsdoc.git - -**Note**: Although you can install JSDoc with npm, JSDoc does not currently run -on Node.js. - - -Usage ------ - -This example assumes that your working directory is the JSDoc application base -directory: - - ./jsdoc yourSourceCodeFile.js - -For information about the supported command-line options, use the `--help` -option. - - ./jsdoc --help - -Generated documentation will appear in the folder specified by the -`--destination` option, or in a folder named "out" by default. - - -Dependencies ------------- - -JSDoc 3 uses the Mozilla Rhino engine, which requires Java. JSDoc 3 is known to -work with version 1.6.0_24 of Java. - -JSDoc 3 uses advanced features in Mozilla Rhino that are only available in or -after version 1.7R3. In addition, JSDoc 3 requires several customizations to the -standard Rhino distribution. The customized version of Rhino is included with -JSDoc. - -In rare cases, users may have their Java CLASSPATH configured to override the -included Rhino and point to an older version of Rhino instead. If this is the -case, simply correct the CLASSPATH to remove the older Rhino. (On OS X, you may -need to remove the file `~/Library/Java/Extensions/js.jar`.) - -The version of Rhino distributed with JSDoc 3 can be found here: -https://github.com/hegemonic/rhino - - -Debugging ---------- - -Rhino is not always very friendly when it comes to reporting errors in -JavaScript. Luckily, it comes with a full-on debugger included that can be much -more useful than a simple stack trace. To invoke JSDoc with the debugger, run -the following command on Windows: - - jsdoc --debug - -Or on OS X, Linux, and other POSIX-compliant systems: - - ./jsdoc --debug - -If you can't get the short-form commands to work, try invoking Java directly: - - java -cp lib/js.jar org.mozilla.javascript.tools.debugger.Main \ - -debug -modules node_modules -modules rhino -modules lib -modules . \ - jsdoc.js your/script.js - -Note: `--debug` must be the first argument to the short-form command. - -This will open a debugging window. Click Debug > Break on Exceptions, then click -Run. If there is an error, you should see exactly where it is in the source -code. - - -See Also --------- - -Project Documentation: (under development) -Project Documentation Source: -JSDoc User's Group: -JSDoc 3 Ant Task: -Project Announcements: - - -License -------- - -JSDoc 3 is copyright (c) 2011-2012 Michael Mathews . - -JSDoc 3 is free software, licensed under the Apache License, Version 2.0. See -the file `LICENSE.md` in this distribution for more details. diff --git a/rsc/scripts/jsdoc/apache-license-2.0.txt b/rsc/scripts/jsdoc/apache-license-2.0.txt deleted file mode 100644 index d6456956..00000000 --- a/rsc/scripts/jsdoc/apache-license-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/rsc/scripts/jsdoc/conf.json b/rsc/scripts/jsdoc/conf.json deleted file mode 100644 index 12bff5bd..00000000 --- a/rsc/scripts/jsdoc/conf.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tags": { - "allowUnknownTags": true - }, - "source": { - "includePattern": ".+\\.js(doc)?$", - "excludePattern": "(^|\\/|\\\\)_" - }, - "plugins": [], - "templates": { - "cleverLinks": false, - "monospaceLinks": false, - "default": { - "outputSourceFiles": true - } - } -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/docs/app.html b/rsc/scripts/jsdoc/docs/app.html deleted file mode 100644 index 9e6e9c81..00000000 --- a/rsc/scripts/jsdoc/docs/app.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - JSDoc: Namespace: app - - - - - - - - - - -
- -

Namespace: app

- - - - - -
- -
-

- app -

- -
- -
-
- - - - -
Data that must be shared across the entire application.
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - -
- - - - - - - - - - - - - - - - - - -
- -
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:54 GMT+0300 (EEST) -
- - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/docs/bookAppointment.html b/rsc/scripts/jsdoc/docs/bookAppointment.html deleted file mode 100644 index 172edfff..00000000 --- a/rsc/scripts/jsdoc/docs/bookAppointment.html +++ /dev/null @@ -1,720 +0,0 @@ - - - - - JSDoc: Class: bookAppointment - - - - - - - - - - -
- -

Class: bookAppointment

- - - - - -
- -
-

- bookAppointment -

- -
Implelements the js part of the appointment booking page.
- -
- -
-
- - - - -
-

new bookAppointment()

- - -
-
- - -
- This class implements the book appointment page functionality. -Once the initialize() method is called the page is fully functional -and can serve the appointment booking process. -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - -

Methods

- -
- -
-

<static> bindEventHandlers()

- - -
-
- - -
- This method binds the necessary event handlers -for the book appointments page. -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

<static> calcEndDatetime() → {string}

- - -
-
- - -
- This method calculates the end datetime of the current appointment. -End datetime is depending on the service and start datetime fieldss. -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- Returns the end datetime in string format. -
- - - -
-
- Type -
-
- -string - - -
-
- - - - -
- - - -
-

<static> getAvailableHours(selDate)

- - -
-
- - -
- This function makes an ajax call and returns the available -hours for the selected service, provider and date. -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
selDate - - -string - - - - The selected date of which the available -hours we need to receive.
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

<static> initialize(bindEventHandlers)

- - -
-
- - -
- This method initializes the book appointment page. -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
bindEventHandlers - - -bool - - - - (OPTIONAL) Determines wether -the default event handlers will be binded to the dom elements.
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

<static> updateConfirmData()

- - -
-
- - -
- Every time this function is executed, it updates the confirmation -page with the latest customer settigns and input for the appointment -booking. -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

<static> validateCustomerDataForm() → {bool}

- - -
-
- - -
- This function validates the customer's data input. -It only checks for empty fields by the time. -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- Returns the validation result. -
- - - -
-
- Type -
-
- -bool - - -
-
- - - - -
- -
- - - - - -
- -
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:24:34 GMT+0300 (EEST) -
- - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/docs/book_appointment.js.html b/rsc/scripts/jsdoc/docs/book_appointment.js.html deleted file mode 100644 index 8965b745..00000000 --- a/rsc/scripts/jsdoc/docs/book_appointment.js.html +++ /dev/null @@ -1,362 +0,0 @@ - - - - - JSDoc: Source: book_appointment.js - - - - - - - - - - -
- -

Source: book_appointment.js

- - - - - -
-
-
/**
- * This class implements the book appointment page functionality. 
- * Once the initialize() method is called the page is fully functional 
- * and can serve the appointment booking process.
- * 
- * @class Implelements the js part of the appointment booking page.
- */
-var bookAppointment = {
-    /**
-     * This method initializes the book appointment page.
-     * 
-     * @param {bool} bindEventHandlers (OPTIONAL) Determines wether 
-     * the default event handlers will be binded to the dom elements.
-     */
-    initialize : function(bindEventHandlers) {
-        if (bindEventHandlers == undefined) {
-            bindEventHandlers = true; // Default value
-        }
-        
-        // Initialize page's components (tooltips, datepickers etc).
-        $('.book-step').qtip({
-            position: {
-                my: 'top center',
-                at: 'bottom center'
-            },
-            style: {
-                classes: 'qtip-green qtip-shadow custom-qtip'
-            }
-        });
-        
-        $('#select-date').datepicker({
-            dateFormat  : 'dd-mm-yy',
-            minDate     : 0,
-            defaultDate : Date.today(),
-            onSelect    : function(dateText, instance) {
-                bookAppointment.getAvailableHours(dateText);
-                bookAppointment.updateConfirmData();
-            }
-        });
-       
-        // Bind the event handlers (might not be necessary every time
-        // we use this class).
-        if (bindEventHandlers) {
-            bookAppointment.bindEventHandlers();
-        }
-       
-        // Execute other necessary operations on startup.
-        $('#select-service').trigger('change');
-    },
-    
-    /**
-     * This method binds the necessary event handlers 
-     * for the book appointments page.
-     */
-    bindEventHandlers : function() {
-        /**
-         * Event : Selected Provider "Changed"
-         */
-        $('#select-provider').change(function() {
-            bookAppointment.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
-            bookAppointment.updateConfirmData();
-        });
-        
-        /**
-         * Event : Selected Service "Changed"
-         * 
-         * When the user clicks on a service, its available providers should 
-         * become visible. 
-         */
-        $('#select-service').change(function() {
-            var currServiceId = $('#select-service').val();
-            $('#select-provider').empty();
-
-            $.each(GlobalVariables.providers, function(indexProvider, provider) {
-                $.each(provider['services'], function(indexService, serviceId) {
-                    // If the current provider is able to provide the selected 
-                    // service, add him to the listbox. 
-                    if (serviceId == currServiceId) { 
-                        var optionHtml = '<option value="' + provider['id'] + '">' 
-                            + provider['last_name']  + ' ' + provider['first_name'] 
-                            + '</option>';
-                        $('#select-provider').append(optionHtml);
-                    }
-                });
-            });
-
-            bookAppointment.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
-            bookAppointment.updateConfirmData();
-        });
-        
-        /**
-         * Event : Next Step Button "Clicked"
-         * 
-         * This handler is triggered every time the user pressed the 
-         * "next" button on the book wizard. Some special tasks might 
-         * be perfomed, depending the current wizard step.
-         */
-        $('.button-next').click(function() {
-            // If we are on the 3rd tab then we will need to validate the user's 
-            // input before proceeding to the next step.
-            if ($(this).attr('data-step_index') == '3') {
-                if (!bookAppointment.validateCustomerDataForm()) {
-                    return; // Validation failed, do not continue.
-                } else {
-                    bookAppointment.updateConfirmData();
-                }
-            }
-            
-            // Display the next step tab (uses jquery animation effect).
-            var nextTabIndex = parseInt($(this).attr('data-step_index')) + 1;
-
-            $(this).parents().eq(1).hide('fade', function() {    
-                $('.active-step').removeClass('active-step');
-                $('#step-' + nextTabIndex).addClass('active-step');
-                $('#book-appointment-' + nextTabIndex).show('fade');
-            });
-        });
-
-        /**
-         * Event : Back Step Button "Clicked"
-         * 
-         * This handler is triggered every time the user pressed the 
-         * "back" button on the book wizard.
-         */
-        $('.button-back').click(function() {
-            var prevTabIndex = parseInt($(this).attr('data-step_index')) - 1;
-
-            $(this).parents().eq(1).hide('fade', function() {    
-                $('.active-step').removeClass('active-step');
-                $('#step-' + prevTabIndex).addClass('active-step');
-                $('#book-appointment-' + prevTabIndex).show('fade');
-            });
-        });
-
-        /**
-         * Event : Available Hour "Click"
-         * 
-         * Triggered whenever the user clicks on an available hour
-         * for his appointment.
-         */
-        $('#available-hours').on('click', '.available-hour', function() {
-            $('.selected-hour').removeClass('selected-hour');
-            $(this).addClass('selected-hour');
-            bookAppointment.updateConfirmData();
-        });
-    },
-    
-    /**
-     * This function makes an ajax call and returns the available 
-     * hours for the selected service, provider and date.
-     * 
-     * @param {string} selDate The selected date of which the available
-     * hours we need to receive.
-     */
-    getAvailableHours : function(selDate) {
-        // Find the selected service duration (it is going to 
-        // be send within the "postData" object.
-        var selServiceDuration = 15; // Default value of duration (in minutes).
-        $.each(GlobalVariables.services, function(index, service) {
-            if (service['id'] == $('#select-service').val()) {
-                selServiceDuration = service['duration']; 
-            }
-        });
-
-        var postData = {
-            'service_id'         : $('#select-service').val(),
-            'provider_id'        : $('#select-provider').val(),
-            'selected_date'      : selDate,
-            'service_duration'   : selServiceDuration
-        };
-
-        // Make ajax post request and get the available hours.
-        var ajaxurl = GlobalVariables.baseUrl + 'appointments/ajax_get_available_hours';
-        jQuery.post(ajaxurl, postData, function(postResponse) {
-            ////////////////////////////////////////////////////////////////////////////////
-            console.log('\n\n Get Available Hours Post Response :', postResponse, '\n\n');
-            ////////////////////////////////////////////////////////////////////////////////
-
-            try {
-                var jsonResponse = jQuery.parseJSON(postResponse);
-                ////////////////////////////////////////////////////////////////////////////////
-                //console.log('\n\n Get Available Hours JSON Response :', jsonResponse, '\n\n');
-                ////////////////////////////////////////////////////////////////////////////////
-
-                // Fill the available time div
-                var currColumn = 1;
-                $('#available-hours').html('<div style="width:50px; float:left;"></div>');
-                $.each(jsonResponse, function(index, availableHour) {
-                    if ((currColumn * 10) < (index + 1)) {
-                        currColumn++;
-                        $('#available-hours').append('<div style="width:50px; float:left;"></div>');
-                    }
-
-                    $('#available-hours div:eq(' + (currColumn - 1) + ')')
-                        .append('<span class="available-hour">' + availableHour + '</span><br/>');
-                });
-
-                // Set the first item as selected.
-                $('.available-hour:eq(0)').addClass('selected-hour');
-                bookAppointment.updateConfirmData();
-            } catch(exception) {
-                GeneralFunctions.displayMessageBox('Unexpected Error', 'An unexpected error occured ' 
-                    + 'during the available hours calculation. Please refresh the page and try again.');
-            }
-        });
-    },
-
-    /**
-     * This function validates the customer's data input.
-     * It only checks for empty fields by the time.
-     * 
-     * @return {bool} Returns the validation result.
-     */
-    validateCustomerDataForm : function() {
-        var validationResult = true;
-        $('.required').css('border', '');
-
-        $('.required').each(function() {
-            if ($(this).val() == '') {
-                validationResult = false; 
-                $(this).css('border', '2px solid red');
-            }
-        });
-
-        return validationResult;
-    },
-
-    /**
-     * Every time this function is executed, it updates the confirmation
-     * page with the latest customer settigns and input for the appointment 
-     * booking.
-     */
-    updateConfirmData : function() {
-        /*** SET APPOINTMENT INFO ***/
-        var selectedDate = $('#select-date').datepicker('getDate');
-        if (selectedDate !== null) {
-            selectedDate = Date.parse(selectedDate).toString('dd-MM-yyyy');
-        }
-
-        $('#appointment-info').html(
-            '<h4>' + $('#select-service option:selected').text() + '</h4>' +
-            $('#select-provider option:selected').text() + '<br/>' + 
-            '<strong class="text-info">' + selectedDate + ' ' 
-                    + $('.selected-hour').text() + '</strong>'
-        );
-
-        /*** SET CUSTOMER'S INFO ***/
-        $('#customer-info').html(
-            '<h4>' + $('#last-name').val() + ' ' + $('#first-name').val() + '</h4>' + 
-            'Phone: ' + $('#phone-number').val() + '<br/>' + 
-            'Email: ' + $('#email').val() + '<br/>' + 
-            'Address: ' + $('#address').val() + '<br/>' + 
-            'City: ' + $('#city').val() + '<br/>' + 
-            'Zip Code: ' + $('#zip-code').val()
-        );
-            
-        /*** UPDATE FORM POST DATA ***/
-        var postData = new Object();
-        
-        postData['customer'] = {
-            'last_name'      : $('#last-name').val(),
-            'first_name'     : $('#first-name').val(),
-            'email'          : $('#email').val(),
-            'phone_number'   : $('#phone-number').val(),
-            'address'        : $('#address').val(),
-            'city'           : $('#city').val(),
-            'zip_code'       : $('#zip-code').val()
-        };
-        
-        postData['appointment'] = {
-            'start_datetime'    : $('#select-date').datepicker('getDate').toString('yyyy-MM-dd') 
-                                        + ' ' + $('.selected-hour').text() + ':00',
-            'end_datetime'      : bookAppointment.calcEndDatetime(),
-            'notes'             : $('#notes').val(),
-            'id_users_provider' : $('#select-provider').val(),
-            'id_services'       : $('#select-service').val()
-        };
-        
-        $('input[name="post_data"]').val(JSON.stringify(postData));
-    },
-    
-    /** 
-     * This method calculates the end datetime of the current appointment. 
-     * End datetime is depending on the service and start datetime fieldss.
-     * 
-     * @return {string} Returns the end datetime in string format.
-     */
-    calcEndDatetime : function() {
-        // Find selected service duration. 
-        var selServiceDuration = undefined;
-        
-        $.each(GlobalVariables.services, function(index, service) {
-            if (service.id == $('#select-service').val()) {
-                selServiceDuration = service.duration;
-                return; // Stop searching ... 
-            }
-        });
-        
-        // Add the duration to the start datetime.
-        var startDatetime = $('#select-date').datepicker('getDate').toString('dd-MM-yyyy') 
-                + ' ' + $('.selected-hour').text();
-        startDatetime = Date.parseExact(startDatetime, 'dd-MM-yyyy HH:mm');
-        var endDatetime = undefined;
-        
-        if (selServiceDuration !== undefined && startDatetime !== null) {
-            endDatetime = startDatetime.add({ 'minutes' : parseInt(selServiceDuration) });
-        } else {
-            endDatetime = new Date();
-        }
-        
-        return endDatetime.toString('yyyy-MM-dd HH:mm:ss');
-    }
-}
-
-
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:24:34 GMT+0300 (EEST) -
- - - - - diff --git a/rsc/scripts/jsdoc/docs/env.html b/rsc/scripts/jsdoc/docs/env.html deleted file mode 100644 index ac7feda5..00000000 --- a/rsc/scripts/jsdoc/docs/env.html +++ /dev/null @@ -1,441 +0,0 @@ - - - - - JSDoc: Namespace: env - - - - - - - - - - -
- -

Namespace: env

- - - - - -
- -
-

- env -

- -
- -
-
- - - - -
Data representing the environment in which this app is running.
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - -
- - - - - - - - - - - - -

Members

- -
- -
-

<static> args :Array

- - -
-
- -
- The command-line arguments passed into JSDoc. -
- - - -
Type:
-
    -
  • - -Array - - -
  • -
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

<static> conf :Object

- - -
-
- -
- The parsed JSON data from the configuration file. -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

<static> opts :Object

- - -
-
- -
- The command-line arguments, parsed into a key/value hash. -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
Example
- -
 if (env.opts.help) { console.log('Helpful message.'); }
- - -
- - - -
-

<static> run

- - -
-
- -
- Running start and finish times. -
- - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

<static> version :Object

- - -
-
- -
- The JSDoc version number and revision date. -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- -
- - - - - - - -
- -
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:54 GMT+0300 (EEST) -
- - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/docs/global.html b/rsc/scripts/jsdoc/docs/global.html deleted file mode 100644 index d57729c3..00000000 --- a/rsc/scripts/jsdoc/docs/global.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - JSDoc: Global - - - - - - - - - - -
- -

Global

- - - - - -
- -
-

- -

- -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - - - -

Methods

- -
- -
-

main()

- - -
-
- - -
- Run the jsdoc application. -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
To Do:
-
-
    -
  • Refactor function (and require statements) into smaller functions
  • -
-
- -
- - - - - - - - - - - - - -
- -
- - - - - -
- -
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:54 GMT+0300 (EEST) -
- - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/docs/index.html b/rsc/scripts/jsdoc/docs/index.html deleted file mode 100644 index 08bfd681..00000000 --- a/rsc/scripts/jsdoc/docs/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - JSDoc: Index - - - - - - - - - - -
- -

Index

- - - - - - - -

- - - - - - - - - - - - - - - - - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:24:34 GMT+0300 (EEST) -
- - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/docs/jsdoc.js.html b/rsc/scripts/jsdoc/docs/jsdoc.js.html deleted file mode 100644 index 2a819f5c..00000000 --- a/rsc/scripts/jsdoc/docs/jsdoc.js.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - JSDoc: Source: jsdoc.js - - - - - - - - - - -
- -

Source: jsdoc.js

- - - - - -
-
-
/*global app: true, args: true, env: true, publish: true */
-/**
- * @project jsdoc
- * @author Michael Mathews <micmath@gmail.com>
- * @license See LICENSE.md file included in this distribution.
- */
-
-// try: $ java -classpath build-files/java/classes/js.jar org.mozilla.javascript.tools.shell.Main main.js `pwd` script/to/parse.js
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
-
-/**
- * Data representing the environment in which this app is running.
- *
- * @namespace
- * @name env
- */
-require('lib/jsdoc/util/global').env = {
-    /**
-     * Running start and finish times.
-     * 
-     * @memberof env
-     */
-    run: {
-        start: new Date(),
-        finish: null
-    },
-
-    /**
-     * The command-line arguments passed into JSDoc.
-     *
-     * @type Array
-     * @memberof env
-     */
-    args: [],
-
-    /**
-     * The parsed JSON data from the configuration file.
-     * 
-     * @type Object
-     * @memberof env
-     */
-    conf: {},
-
-    /**
-     * The absolute path to the base directory of the JSDoc application.
-     * 
-     * @private
-     * @deprecated Use `__dirname` instead.
-     * @type string
-     * @memberof env
-     */
-    dirname: '.',
-
-    /**
-     * The command-line arguments, parsed into a key/value hash.
-     * 
-     * @type Object
-     * @memberof env
-     * @example if (env.opts.help) { console.log('Helpful message.'); }
-    */
-    opts: {},
-
-    /**
-     * The JSDoc version number and revision date.
-     * 
-     * @type Object
-     * @memberof env
-     */
-    version: {}
-};
-
-// initialize the environment for the current JavaScript VM
-(function(args) {
-    var vm = require('jsdoc/util/vm').vm;
-    // TODO: may need to move this file to support Node.js
-    require('initialize')[vm](args);
-})( Array.prototype.slice.call(arguments, 0) );
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
-
-/**
- * Data that must be shared across the entire application.
- * @namespace
- * @name app
- */
-require('lib/jsdoc/util/global').app = {
-    jsdoc: {
-        scanner: new (require('jsdoc/src/scanner').Scanner)(),
-        parser: new (require('jsdoc/src/parser').Parser)(),
-        name: require('jsdoc/name')
-    }
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
-
-/**
-    Try to recursively print out all key/values in an object.
-    @global
-    @private
-    @param {Object} ... Object/s to dump out to console.
- */
-function dump() {
-    var doop = require('jsdoc/util/doop').doop;
-    var _dump = require('jsdoc/util/dumper').dump;
-    for (var i = 0, l = arguments.length; i < l; i++) {
-        console.log( _dump(doop(arguments[i])) );
-    }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
-
-/**
- * Run the jsdoc application.
- * @todo Refactor function (and require statements) into smaller functions
- */
-function main() {
-    var _ = require('underscore');
-    var fs = require('jsdoc/fs');
-    var path = require('jsdoc/path');
-    var taffy = require('taffydb').taffy;
-
-    var jsdoc = {
-        augment: require('jsdoc/augment'),
-        borrow: require('jsdoc/borrow'),
-        Config: require('jsdoc/config'),
-        opts: {
-            args: require('jsdoc/opts/args')
-        },
-        'package': require('jsdoc/package'),
-        plugins: require('jsdoc/plugins'),
-        Readme: require('jsdoc/readme'),
-        src: {
-            filter: require('jsdoc/src/filter'),
-            handlers: require('jsdoc/src/handlers')
-        },
-        tutorial: {
-            resolver: require('jsdoc/tutorial/resolver')
-        },
-        util: {
-            include: require('jsdoc/util/include')
-        }
-    };
-
-    var confPath;
-    var defaultOpts;
-    var docs;
-    var filter;
-    var i;
-    var info;
-    var l;
-    var packageDocs;
-    var packageJson;
-    var sourceFiles;
-    var template;
-
-
-    defaultOpts = {
-        destination: './out/',
-        encoding: 'utf8'
-    };
-
-    // get JSDoc version number
-    info = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
-    env.version = {
-        number: info.version,
-        revision: new Date(parseInt(info.revision, 10)).toUTCString()
-    };
-
-    env.opts = jsdoc.opts.args.parse(env.args);
-
-    confPath = env.opts.configure || path.join(__dirname, 'conf.json');
-    if ( !fs.statSync(confPath).isFile() ) {
-        confPath = path.join(__dirname, 'conf.json.EXAMPLE');
-    }
-
-    try {
-        env.conf = new jsdoc.Config( fs.readFileSync(confPath, 'utf8') )
-            .get();
-    }
-    catch (e) {
-        throw new Error('Cannot parse the config file ' + confPath + ': ' + e);
-    }
-
-    // look for options on the command line, in the config file, and in the defaults, in that order
-    env.opts = _.defaults(env.opts, env.conf.opts, defaultOpts);
-
-    if (env.opts.help) {
-        console.log( jsdoc.opts.args.help() );
-        process.exit(0);
-    } else if (env.opts.test) {
-        jsdoc.util.include('test/runner.js');
-        process.exit(0);
-    } else if (env.opts.version) {
-        console.log('JSDoc ' + env.version.number + ' (' + env.version.revision + ')');
-        process.exit(0);
-    }
-
-    if (env.conf.plugins) {
-        jsdoc.plugins.installPlugins(env.conf.plugins, app.jsdoc.parser);
-    }
-    
-    if (env.conf.source && env.conf.source.include) {
-        env.opts._ = (env.opts._ || []).concat(env.conf.source.include);
-    }
-
-    // any source file named package.json or README.md is treated special
-    for (i = 0, l = env.opts._.length; i < l; i++ ) {
-        if (/\bpackage\.json$/i.test(env.opts._[i])) {
-            packageJson = fs.readFileSync( env.opts._[i], 'utf8' );
-            env.opts._.splice(i--, 1);
-        }
-        
-        if (/(\bREADME|\.md)$/i.test(env.opts._[i])) {
-            env.opts.readme = new jsdoc.Readme(env.opts._[i]).html;
-            env.opts._.splice(i--, 1);
-        }
-    }
-    
-    if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse?
-        filter = new jsdoc.src.filter.Filter(env.conf.source);
-
-        sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), filter);
-
-        jsdoc.src.handlers.attachTo(app.jsdoc.parser);
-
-        docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding);
-
-        //The files are ALWAYS useful for the templates to have
-        //If there is no package.json, just create an empty package
-        packageDocs = new jsdoc.package.Package(packageJson);
-        packageDocs.files = sourceFiles || [];
-        docs.push(packageDocs);
-
-        jsdoc.borrow.indexAll(docs);
-
-        jsdoc.augment.addInherited(docs);
-        jsdoc.borrow.resolveBorrows(docs);
-
-        if (env.opts.explain) {
-            dump(docs);
-            process.exit(0);
-        }
-
-        if (env.opts.tutorials) {
-            jsdoc.tutorial.resolver.load(env.opts.tutorials);
-            jsdoc.tutorial.resolver.resolve();
-        }
-
-        env.opts.template = (function() {
-            var publish = env.opts.template || 'templates/default';
-            // if we don't find it, keep the user-specified value so the error message is useful
-            return path.getResourcePath(publish) || env.opts.template;
-        })();
-
-        try {
-            template = require(env.opts.template + '/publish');
-        }
-        catch(e) {
-            throw new Error('Unable to load template: ' + e.message || e);
-        }
-
-        // templates should include a publish.js file that exports a "publish" function
-        if (template.publish && typeof template.publish === 'function') {
-            // convert this from a URI back to a path if necessary
-            env.opts.template = path._uriToPath(env.opts.template);
-            template.publish(
-                taffy(docs),
-                env.opts,
-                jsdoc.tutorial.resolver.root
-            );
-        }
-        else {
-            // old templates define a global "publish" function, which is deprecated
-            jsdoc.util.include(env.opts.template + '/publish.js');
-            if (publish && typeof publish === 'function') {
-                console.log( env.opts.template + ' uses a global "publish" function, which is ' +
-                    'deprecated and may not be supported in future versions. ' +
-                    'Please update the template to use "exports.publish" instead.' );
-                // convert this from a URI back to a path if necessary
-                env.opts.template = path._uriToPath(env.opts.template);
-                publish(
-                    taffy(docs),
-                    env.opts,
-                    jsdoc.tutorial.resolver.root
-                );
-            }
-            else {
-                throw new Error( env.opts.template + ' does not export a "publish" function.' );
-            }
-        }
-    }
-}
-
-try {
-    main();
-    env.run.finish = new Date();
-    process.exit(0);
-}
-catch(e) {
-    env.run.finish = new Date();
-    if (e.rhinoException != null) {
-        e.rhinoException.printStackTrace();
-        process.exit(1);
-    } else {
-        throw e;
-    }
-}
-
-
-
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:54 GMT+0300 (EEST) -
- - - - - diff --git a/rsc/scripts/jsdoc/docs/scripts/linenumber.js b/rsc/scripts/jsdoc/docs/scripts/linenumber.js deleted file mode 100644 index a0c570d5..00000000 --- a/rsc/scripts/jsdoc/docs/scripts/linenumber.js +++ /dev/null @@ -1,17 +0,0 @@ -(function() { - var counter = 0; - var numbered; - var source = document.getElementsByClassName('prettyprint source'); - - if (source && source[0]) { - source = source[0].getElementsByTagName('code')[0]; - - numbered = source.innerHTML.split('\n'); - numbered = numbered.map(function(item) { - counter++; - return '' + item; - }); - - source.innerHTML = numbered.join('\n'); - } -})(); diff --git a/rsc/scripts/jsdoc/docs/scripts/prettify/Apache-License-2.0.txt b/rsc/scripts/jsdoc/docs/scripts/prettify/Apache-License-2.0.txt deleted file mode 100644 index d6456956..00000000 --- a/rsc/scripts/jsdoc/docs/scripts/prettify/Apache-License-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/rsc/scripts/jsdoc/docs/scripts/prettify/lang-css.js b/rsc/scripts/jsdoc/docs/scripts/prettify/lang-css.js deleted file mode 100644 index 041e1f59..00000000 --- a/rsc/scripts/jsdoc/docs/scripts/prettify/lang-css.js +++ /dev/null @@ -1,2 +0,0 @@ -PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", -/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/rsc/scripts/jsdoc/docs/scripts/prettify/prettify.js b/rsc/scripts/jsdoc/docs/scripts/prettify/prettify.js deleted file mode 100644 index eef5ad7e..00000000 --- a/rsc/scripts/jsdoc/docs/scripts/prettify/prettify.js +++ /dev/null @@ -1,28 +0,0 @@ -var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; -(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= -[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), -l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, -q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, -q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, -"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), -a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} -for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], -"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], -H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], -J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ -I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), -["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", -/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), -["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", -hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= -!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p/dev/null || cygpath -w $(pwd) 2>/dev/null || pwd))" -if [ "${BASEPATH%${BASEPATH#?}}" != "/" ] ; then - BASEPATH="$( echo "$BASEPATH" | sed -e 's@\\@/@g' )" - # We need a extra slash for URLs - UBASEPATH="/$BASEPATH" -else - UBASEPATH="$BASEPATH" -fi - -# for whatever reason, Rhino requires module paths to be valid URIs -URLPATH="file://$UBASEPATH" -URLPATH=`echo "$URLPATH" | sed -e 's/ /%20/g'` -ENCODEDBASEPATH=`echo "$BASEPATH" | sed -e 's/ /%20/g'` - -if test "$1" = "--debug" -then - echo "Running Debug" - CMD="org.mozilla.javascript.tools.debugger.Main -debug" - # strip --debug argument - shift -else - CMD="org.mozilla.javascript.tools.shell.Main" -fi - -#Conditionally execute different command lines depending on whether we're running tests or not -if test "$1" = "-T" -then - echo "Running Tests" - cd -P "$(dirname "$SOURCE")" - java -classpath "${BASEPATH}/rhino/js.jar" ${CMD} -opt -1 -modules "${URLPATH}/node_modules" -modules "${URLPATH}/rhino" -modules "${URLPATH}/lib" -modules "${URLPATH}" "${BASEPATH}/jsdoc.js" "$@" --dirname="${BASEPATH}/" - -else - # normal mode should be quiet - java -classpath "${BASEPATH}/rhino/js.jar" ${CMD} -modules "${URLPATH}/node_modules" -modules "${URLPATH}/rhino" -modules "${URLPATH}/lib" -modules "${URLPATH}" "${BASEPATH}/jsdoc.js" "$@" --dirname="${BASEPATH}/" -fi diff --git a/rsc/scripts/jsdoc/jsdoc.cmd b/rsc/scripts/jsdoc/jsdoc.cmd deleted file mode 100644 index a2ef8f11..00000000 --- a/rsc/scripts/jsdoc/jsdoc.cmd +++ /dev/null @@ -1,45 +0,0 @@ -@ECHO OFF - -SETLOCAL - -REM jsdoc.js expects Unix-style paths without a trailing slash -SET _BASEPATH=%~dp0 -SET _BASEPATH=%_BASEPATH:\=/% -SET _BASEPATH=%_BASEPATH:~0,-1% - -REM for whatever reason, Rhino requires module paths to be valid URIs -SET _URLPATH=file:/%_BASEPATH% - -IF "%_URLPATH%"=="%_URLPATH: =%" GOTO NO_SPACES -:ESCAPE_SPACE -SET _TRAILING=%_URLPATH:* =% -CALL SET _URLPATH=%%_URLPATH: %_TRAILING%=%% -SET _URLPATH=%_URLPATH%%%20%_TRAILING% -IF NOT "%_URLPATH%"=="%_URLPATH: =%" GOTO ESCAPE_SPACE -:NO_SPACES - -IF [%1]==[--debug] ( - ECHO Running Debug - SET CMD=org.mozilla.javascript.tools.debugger.Main -debug - - REM `SHIFT` doesn't affect %* - :COLLECT_ARGS - IF [%2]==[] GOTO LAST_ARG - SET ARGS=%ARGS% %2 - SHIFT - GOTO COLLECT_ARGS -) ELSE ( - SET CMD=org.mozilla.javascript.tools.shell.Main - SET ARGS=%* -) -:LAST_ARG - -IF [%1]==[-T] ( - ECHO Running Tests - java -classpath "%_BASEPATH%/rhino/js.jar" %CMD% -opt -1 -modules "%_URLPATH%/node_modules" -modules "%_URLPATH%/rhino" -modules "%_URLPATH%/lib" -modules "%_URLPATH%" "%_BASEPATH%/jsdoc.js" %ARGS% --nocolor --dirname="%_BASEPATH%/ -) ELSE ( - REM normal mode should be quiet - java -classpath "%_BASEPATH%/rhino/js.jar" %CMD% -modules "%_URLPATH%/node_modules" -modules "%_URLPATH%/rhino" -modules "%_URLPATH%/lib" -modules "%_URLPATH%" "%_BASEPATH%/jsdoc.js" %ARGS% --dirname="%_BASEPATH%/ -) - -ENDLOCAL diff --git a/rsc/scripts/jsdoc/jsdoc.js b/rsc/scripts/jsdoc/jsdoc.js deleted file mode 100644 index 0204ff61..00000000 --- a/rsc/scripts/jsdoc/jsdoc.js +++ /dev/null @@ -1,308 +0,0 @@ -/*global app: true, args: true, env: true, publish: true */ -/** - * @project jsdoc - * @author Michael Mathews - * @license See LICENSE.md file included in this distribution. - */ - -// try: $ java -classpath build-files/java/classes/js.jar org.mozilla.javascript.tools.shell.Main main.js `pwd` script/to/parse.js - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -/** - * Data representing the environment in which this app is running. - * - * @namespace - * @name env - */ -require('lib/jsdoc/util/global').env = { - /** - * Running start and finish times. - * - * @memberof env - */ - run: { - start: new Date(), - finish: null - }, - - /** - * The command-line arguments passed into JSDoc. - * - * @type Array - * @memberof env - */ - args: [], - - /** - * The parsed JSON data from the configuration file. - * - * @type Object - * @memberof env - */ - conf: {}, - - /** - * The absolute path to the base directory of the JSDoc application. - * - * @private - * @deprecated Use `__dirname` instead. - * @type string - * @memberof env - */ - dirname: '.', - - /** - * The command-line arguments, parsed into a key/value hash. - * - * @type Object - * @memberof env - * @example if (env.opts.help) { console.log('Helpful message.'); } - */ - opts: {}, - - /** - * The JSDoc version number and revision date. - * - * @type Object - * @memberof env - */ - version: {} -}; - -// initialize the environment for the current JavaScript VM -(function(args) { - var vm = require('jsdoc/util/vm').vm; - // TODO: may need to move this file to support Node.js - require('initialize')[vm](args); -})( Array.prototype.slice.call(arguments, 0) ); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -/** - * Data that must be shared across the entire application. - * @namespace - * @name app - */ -require('lib/jsdoc/util/global').app = { - jsdoc: { - scanner: new (require('jsdoc/src/scanner').Scanner)(), - parser: new (require('jsdoc/src/parser').Parser)(), - name: require('jsdoc/name') - } -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -/** - Try to recursively print out all key/values in an object. - @global - @private - @param {Object} ... Object/s to dump out to console. - */ -function dump() { - var doop = require('jsdoc/util/doop').doop; - var _dump = require('jsdoc/util/dumper').dump; - for (var i = 0, l = arguments.length; i < l; i++) { - console.log( _dump(doop(arguments[i])) ); - } -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -/** - * Run the jsdoc application. - * @todo Refactor function (and require statements) into smaller functions - */ -function main() { - var _ = require('underscore'); - var fs = require('jsdoc/fs'); - var path = require('jsdoc/path'); - var taffy = require('taffydb').taffy; - - var jsdoc = { - augment: require('jsdoc/augment'), - borrow: require('jsdoc/borrow'), - Config: require('jsdoc/config'), - opts: { - args: require('jsdoc/opts/args') - }, - 'package': require('jsdoc/package'), - plugins: require('jsdoc/plugins'), - Readme: require('jsdoc/readme'), - src: { - filter: require('jsdoc/src/filter'), - handlers: require('jsdoc/src/handlers') - }, - tutorial: { - resolver: require('jsdoc/tutorial/resolver') - }, - util: { - include: require('jsdoc/util/include') - } - }; - - var confPath; - var defaultOpts; - var docs; - var filter; - var i; - var info; - var l; - var packageDocs; - var packageJson; - var sourceFiles; - var template; - - - defaultOpts = { - destination: './out/', - encoding: 'utf8' - }; - - // get JSDoc version number - info = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8')); - env.version = { - number: info.version, - revision: new Date(parseInt(info.revision, 10)).toUTCString() - }; - - env.opts = jsdoc.opts.args.parse(env.args); - - confPath = env.opts.configure || path.join(__dirname, 'conf.json'); - if ( !fs.statSync(confPath).isFile() ) { - confPath = path.join(__dirname, 'conf.json.EXAMPLE'); - } - - try { - env.conf = new jsdoc.Config( fs.readFileSync(confPath, 'utf8') ) - .get(); - } - catch (e) { - throw new Error('Cannot parse the config file ' + confPath + ': ' + e); - } - - // look for options on the command line, in the config file, and in the defaults, in that order - env.opts = _.defaults(env.opts, env.conf.opts, defaultOpts); - - if (env.opts.help) { - console.log( jsdoc.opts.args.help() ); - process.exit(0); - } else if (env.opts.test) { - jsdoc.util.include('test/runner.js'); - process.exit(0); - } else if (env.opts.version) { - console.log('JSDoc ' + env.version.number + ' (' + env.version.revision + ')'); - process.exit(0); - } - - if (env.conf.plugins) { - jsdoc.plugins.installPlugins(env.conf.plugins, app.jsdoc.parser); - } - - if (env.conf.source && env.conf.source.include) { - env.opts._ = (env.opts._ || []).concat(env.conf.source.include); - } - - // any source file named package.json or README.md is treated special - for (i = 0, l = env.opts._.length; i < l; i++ ) { - if (/\bpackage\.json$/i.test(env.opts._[i])) { - packageJson = fs.readFileSync( env.opts._[i], 'utf8' ); - env.opts._.splice(i--, 1); - } - - if (/(\bREADME|\.md)$/i.test(env.opts._[i])) { - env.opts.readme = new jsdoc.Readme(env.opts._[i]).html; - env.opts._.splice(i--, 1); - } - } - - if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse? - filter = new jsdoc.src.filter.Filter(env.conf.source); - - sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), filter); - - jsdoc.src.handlers.attachTo(app.jsdoc.parser); - - docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding); - - //The files are ALWAYS useful for the templates to have - //If there is no package.json, just create an empty package - packageDocs = new jsdoc.package.Package(packageJson); - packageDocs.files = sourceFiles || []; - docs.push(packageDocs); - - jsdoc.borrow.indexAll(docs); - - jsdoc.augment.addInherited(docs); - jsdoc.borrow.resolveBorrows(docs); - - if (env.opts.explain) { - dump(docs); - process.exit(0); - } - - if (env.opts.tutorials) { - jsdoc.tutorial.resolver.load(env.opts.tutorials); - jsdoc.tutorial.resolver.resolve(); - } - - env.opts.template = (function() { - var publish = env.opts.template || 'templates/default'; - // if we don't find it, keep the user-specified value so the error message is useful - return path.getResourcePath(publish) || env.opts.template; - })(); - - try { - template = require(env.opts.template + '/publish'); - } - catch(e) { - throw new Error('Unable to load template: ' + e.message || e); - } - - // templates should include a publish.js file that exports a "publish" function - if (template.publish && typeof template.publish === 'function') { - // convert this from a URI back to a path if necessary - env.opts.template = path._uriToPath(env.opts.template); - template.publish( - taffy(docs), - env.opts, - jsdoc.tutorial.resolver.root - ); - } - else { - // old templates define a global "publish" function, which is deprecated - jsdoc.util.include(env.opts.template + '/publish.js'); - if (publish && typeof publish === 'function') { - console.log( env.opts.template + ' uses a global "publish" function, which is ' + - 'deprecated and may not be supported in future versions. ' + - 'Please update the template to use "exports.publish" instead.' ); - // convert this from a URI back to a path if necessary - env.opts.template = path._uriToPath(env.opts.template); - publish( - taffy(docs), - env.opts, - jsdoc.tutorial.resolver.root - ); - } - else { - throw new Error( env.opts.template + ' does not export a "publish" function.' ); - } - } - } -} - -try { - main(); - env.run.finish = new Date(); - process.exit(0); -} -catch(e) { - env.run.finish = new Date(); - if (e.rhinoException != null) { - e.rhinoException.printStackTrace(); - process.exit(1); - } else { - throw e; - } -} diff --git a/rsc/scripts/jsdoc/lib/initialize.js b/rsc/scripts/jsdoc/lib/initialize.js deleted file mode 100644 index 774b9d76..00000000 --- a/rsc/scripts/jsdoc/lib/initialize.js +++ /dev/null @@ -1,40 +0,0 @@ -/*global env: true */ -exports.rhino = function(args) { - var myGlobal = require('jsdoc/util/global'); - - // note: mutates args - function getDirname() { - var dirname; - - // Rhino has no native way to get the base dirname of the current script, - // so this information must be manually passed in from the command line. - for (var i = 0; i < args.length; i++) { - if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) { - if (RegExp.$1) { - dirname = RegExp.$1; // last wins - args.splice(i--, 1); // remove --dirname opt from arguments - } - else { - dirname = args[i + 1]; - args.splice(i--, 2); - } - } - } - - return dirname; - } - - myGlobal.__dirname = env.dirname = getDirname(); - env.args = args; - - require('jsdoc/util/include')(__dirname + '/rhino/rhino-shim.js'); -}; - -exports.nodejs = function(args) { - throw new Error('Node.js is not currently supported!'); - /* - env.dirname = __dirname; - env.args = args; - // TODO: add lib/ to the library paths - */ -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/augment.js b/rsc/scripts/jsdoc/lib/jsdoc/augment.js deleted file mode 100644 index eaa00a48..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/augment.js +++ /dev/null @@ -1,138 +0,0 @@ -var hasOwnProp = Object.prototype.hasOwnProperty; - -function mapDependencies(index) { - var doclets, doc, len, dependencies = {}; - - Object.keys(index).forEach(function(name) { - doclets = index[name]; - for (var i = 0, ii = doclets.length; i < ii; ++i) { - doc = doclets[i]; - if (doc.kind === "class" || doc.kind === "external") { - dependencies[name] = {}; - len = doc.augments && doc.augments.length || 0; - for (var j = 0; j < len; ++j) { - dependencies[name][doc.augments[j]] = true; - } - } - } - }); - - return dependencies; -} - -function Sorter(dependencies) { - this.dependencies = dependencies; - this.visited = {}; - this.sorted = []; -} - -Sorter.prototype.visit = function(key) { - var self = this; - - if (!(key in this.visited)) { - this.visited[key] = true; - - if (this.dependencies[key]) { - Object.keys(this.dependencies[key]).forEach(function(path) { - self.visit(path); - }); - } - - this.sorted.push(key); - } -}; - -Sorter.prototype.sort = function() { - var self = this; - - Object.keys(this.dependencies).forEach(function(key) { - self.visit(key); - }); - - return this.sorted; -}; - -function sort(dependencies) { - var sorter = new Sorter(dependencies); - return sorter.sort(); -} - -function getMembers(longname, docs) { - var candidate, members = []; - for (var i = 0, ii = docs.length; i < ii; ++i) { - candidate = docs[i]; - if (candidate.memberof === longname && candidate.scope === "instance") { - members.push(candidate); - } - } - return members; -} - -function getAdditions(doclets, docs, longnames) { - var doop = require("jsdoc/util/doop").doop; - - var additions = []; - var doc; - var parents; - var members; - var member; - var parts; - - // doclets will be undefined if the inherited symbol isn't documented - doclets = doclets || []; - - for (var i = 0, ii = doclets.length; i < ii; i++) { - doc = doclets[i]; - parents = doc.augments; - if (parents && doc.kind === "class") { - for (var j = 0, jj = parents.length; j < jj; j++) { - members = getMembers(parents[j], docs); - for (var k = 0, kk = members.length; k < kk; k++) { - member = doop(members[k]); - - member.inherits = member.longname; - member.inherited = true; - - member.memberof = doc.longname; - parts = member.longname.split("#"); - parts[0] = doc.longname; - member.longname = parts.join("#"); - - // if the child doesn't override the parent member, add the parent member - if (longnames.indexOf(member.longname) === -1) { - additions.push(member); - } - } - } - } - } - return additions; -} - -exports.addInherited = function(docs) { - var dependencies = mapDependencies(docs.index); - var sorted = sort(dependencies); - var longnames = []; - - // only build the list of longnames if we'll actually need it - if (sorted.length) { - longnames = docs.map(function(doc) { - if (doc.longname) { - return doc.longname; - } - }); - } - - sorted.forEach(function(name) { - var doclets = docs.index[name]; - var additions = getAdditions(doclets, docs, longnames); - additions.forEach(function(doc) { - var name = doc.longname; - if ( !hasOwnProp.call(docs.index, name) ) { - docs.index[name] = []; - } - docs.index[name].push(doc); - docs.push(doc); - }); - }); -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/borrow.js b/rsc/scripts/jsdoc/lib/jsdoc/borrow.js deleted file mode 100644 index 5cc13ca5..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/borrow.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - A collection of functions relating to resolving @borrows tags in JSDoc symbols. - @module jsdoc/borrow - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var doop = require("jsdoc/util/doop").doop; - -var hasOwnProp = Object.prototype.hasOwnProperty; - -exports.indexAll = function(docs) { - var lookupTable = {}; - - docs.forEach(function(doc) { - if ( !hasOwnProp.call(lookupTable, doc.longname) ) { - lookupTable[doc.longname] = []; - } - lookupTable[doc.longname].push(doc); - }); - docs.index = lookupTable; -}; - -// requires docs to have been indexed: docs.index must be defined here -/** - Take a copy of the docs for borrowed symbols and attach them to the - docs for the borrowing symbol. This process changes the symbols involved, - moving docs from the "borrowed" array and into the general docs, then - deleting the "borrowed" array. - */ -exports.resolveBorrows = function(docs) { - if (!docs.index) { - throw 'Docs has not been indexed: docs.index must be defined here.'; - } - - docs.forEach(function(doc) { - if (doc.borrowed) { - doc.borrowed.forEach(function(b, i) { - var lent = docs.index[b.from], // lent is an array - asName = b.as || b.from; - - if (lent) { - var cloned = doop(lent); - - cloned.forEach(function(clone) { - asName = asName.replace(/^prototype\./, '#'); - var parts = asName.split('#'); - - if (parts.length === 2) { clone.scope = 'instance'; } - else { clone.scope = 'static'; } - - asName = parts.pop(); - clone.name = asName; - clone.memberof = doc.longname; - clone.longname = clone.memberof + (clone.scope === 'instance'? '#': '.') + clone.name; - docs.push(clone); - }); - - } - }); - - delete doc.borrowed; - } - }); -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/config.js b/rsc/scripts/jsdoc/lib/jsdoc/config.js deleted file mode 100644 index 9b6a52c4..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/config.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - @overview - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - @module jsdoc/config - */ - -function mergeRecurse(target, source) { - Object.keys(source).forEach(function(p) { - if ( source[p].constructor === Object ) { - if ( !target[p] ) { target[p] = {}; } - mergeRecurse(target[p], source[p]); - } - else { - target[p] = source[p]; - } - }); - - return target; -} - -// required config values, override these defaults in your config.json if necessary -const defaults = { - "tags": { - "allowUnknownTags": true - }, - "templates": { - "monospaceLinks": false, - "cleverLinks": false - }, - "source": { - "includePattern": ".+\\.js(doc)?$", - "excludePattern": "(^|\\/)_" - }, - "plugins": [] -}; - -/** - @class - @classdesc Represents a JSDoc application configuration. - @param {string} [json] - The contents of config.json. - */ -function Config(json) { - json = JSON.parse( (json || "{}") ); - this._config = mergeRecurse(defaults, json); -} - -module.exports = Config; - -/** - Get the merged configuration values. - */ -Config.prototype.get = function() { - return this._config; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/doclet.js b/rsc/scripts/jsdoc/lib/jsdoc/doclet.js deleted file mode 100644 index 47f833c0..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/doclet.js +++ /dev/null @@ -1,337 +0,0 @@ -/** - @overview - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - @module jsdoc/doclet - @requires jsdoc/tag - @requires jsdoc/name - @requires jsdoc/tag/dictionary - */ - -var jsdoc = { - tag: { - Tag: require('jsdoc/tag').Tag, - dictionary: require('jsdoc/tag/dictionary') - }, - name: require('jsdoc/name') -}; -var path = require('path'); - - -function applyTag(tag) { - if (tag.title === 'name') { - this.name = tag.value; - } - - if (tag.title === 'kind') { - this.kind = tag.value; - } - - if (tag.title === 'description') { - this.description = tag.value; - } - - if (tag.title === 'scope') { - this.scope = tag.value; - } -} - -// use the meta info about the source code to guess what the doclet kind should be -function codetypeToKind(type) { - var kind = (type || '').toLowerCase(); - - if (kind !== 'function') { - return 'member'; - } - - return kind; -} - -function unwrap(docletSrc) { - if (!docletSrc) { return ''; } - - // note: keep trailing whitespace for @examples - // extra opening/closing stars are ignored - // left margin is considered a star and a space - // use the /m flag on regex to avoid having to guess what this platform's newline is - docletSrc = - docletSrc.replace(/^\/\*\*+/, '') // remove opening slash+stars - .replace(/\**\*\/$/, "\\Z") // replace closing star slash with end-marker - .replace(/^\s*(\* ?|\\Z)/gm, '') // remove left margin like: spaces+star or spaces+end-marker - .replace(/\s*\\Z$/g, ''); // remove end-marker - - return docletSrc; -} - -function split(docletSrc) { - var tagSrcs = [], - tagText, - tagTitle; - - // split out the basic tags, keep surrounding whitespace - // like: @tagTitle tagBody - docletSrc - .replace(/^(\s*)@(\S)/gm, '$1\\@$2') // replace splitter ats with an arbitrary sequence - .split('\\@') // then split on that arbitrary sequence - .forEach(function($) { - if ($) { - var parsedTag = $.match(/^(\S+)(:?\s+(\S[\s\S]*))?/); - - if (parsedTag) { - // we don't need parsedTag[0] - tagTitle = parsedTag[1]; - tagText = parsedTag[2]; - - if (tagTitle) { - tagSrcs.push({ - title: tagTitle, - text: tagText - }); - } - } - } - }); - - return tagSrcs; -} - -/** - Convert the raw source of the doclet comment into an array of Tag objects. - @private - */ -function toTags(docletSrc) { - var tagSrcs, - tags = []; - - tagSrcs = split(docletSrc); - - for (var i = 0, l = tagSrcs.length; i < l; i++) { - tags.push( {title: tagSrcs[i].title, text: tagSrcs[i].text} ); - } - - return tags; -} - -function fixDescription(docletSrc) { - if (!/^\s*@/.test(docletSrc)) { - docletSrc = '@description ' + docletSrc; - } - return docletSrc; -} - -/** - @class - @classdesc Represents a single JSDoc comment. - @param {string} docletSrc - The raw source code of the jsdoc comment. - @param {object=} meta - Properties describing the code related to this comment. - */ -exports.Doclet = function(docletSrc, meta) { - var newTags = []; - - /** The original text of the comment from the source code. */ - this.comment = docletSrc; - this.setMeta(meta); - - docletSrc = unwrap(docletSrc); - docletSrc = fixDescription(docletSrc); - - newTags = toTags.call(this, docletSrc); - - for (var i = 0, leni = newTags.length; i < leni; i++) { - this.addTag(newTags[i].title, newTags[i].text); - } - - this.postProcess(); -}; - -/** Called once after all tags have been added. */ -exports.Doclet.prototype.postProcess = function() { - if (!this.preserveName) { jsdoc.name.resolve(this); } - if (this.name && !this.longname) { - this.setLongname(this.name); - } - if (this.memberof === '') { - delete(this.memberof); - } - - if (!this.kind && this.meta && this.meta.code) { - this.addTag( 'kind', codetypeToKind(this.meta.code.type) ); - } - - if (this.variation && this.longname && !/\)$/.test(this.longname) ) { - this.longname += '('+this.variation+')'; - } - - // add in any missing param names - if (this.params && this.meta && this.meta.code && this.meta.code.paramnames) { - for (var i = 0, len = this.params.length; i < len; i++) { - if (!this.params[i].name) { - this.params[i].name = this.meta.code.paramnames[i] || ''; - } - } - } -}; - -/** Add a tag to this doclet. - @param {string} title - The title of the tag being added. - @param {string} [text] - The text of the tag being added. -*/ -exports.Doclet.prototype.addTag = function(title, text) { - var tagDef = jsdoc.tag.dictionary.lookUp(title), - newTag = new jsdoc.tag.Tag(title, text, this.meta); - - if (tagDef && tagDef.onTagged) { - tagDef.onTagged(this, newTag); - } - - if (!tagDef) { - this.tags = this.tags || []; - this.tags.push(newTag); - } - - applyTag.call(this, newTag); -}; - -/** Set the `memberof` property of this doclet. - @param {string} sid - The longname of the symbol that this doclet is a member of. -*/ -exports.Doclet.prototype.setMemberof = function(sid) { - if (/^\.?/.test(sid)) { sid = sid.replace(/^.?/, ''); } - /** - The longname of the symbol that contains this one, if any. - @type string - */ - this.memberof = sid.replace(/\.prototype/g, '#'); -}; - -/** Set the `longname` property of this doclet. - @param {string} name -*/ -exports.Doclet.prototype.setLongname = function(name) { - if (/^\.?/.test(name)) { name = name.replace(/^\.?/, ''); } - - /** - The fully resolved symbol name. - @type string - */ - this.longname = name; - if (jsdoc.tag.dictionary.isNamespace(this.kind)) { - this.longname = jsdoc.name.applyNamespace(this.longname, this.kind); - } -}; - -/** Add a symbol to this doclet's `borrowed` array. - @param {string} source - The longname of the symbol that is the source. - @param {string} target - The name the symbol is being assigned to. -*/ -exports.Doclet.prototype.borrow = function(source, target) { - var about = {from: source}; - if (target) { about.as = target; } - - if (!this.borrowed) { - /** - A list of symbols that are borrowed by this one, if any. - @type Array. - */ - this.borrowed = []; - } - this.borrowed.push(about); -}; - -exports.Doclet.prototype.mix = function(source) { - if (!this.mixes) { - /** - A list of symbols that are mixed into this one, if any. - @type Array. - */ - this.mixes = []; - } - this.mixes.push(source); -}; - -/** Add a symbol to this doclet's `augments` array. - @param {string} base - The longname of the base symbol. -*/ -exports.Doclet.prototype.augment = function(base) { - if (!this.augments) { - /** - A list of symbols that are augmented by this one, if any. - @type Array. - */ - this.augments = []; - } - this.augments.push(base); -}; - -/** - Set the `meta` property of this doclet. - @param {object} meta -*/ -exports.Doclet.prototype.setMeta = function(meta) { - if (!this.meta) { - /** - Information about the source code associated with this doclet. - @namespace - */ - this.meta = {}; - } - - if (meta.range) { - /** - The positions of the first and last characters of the code associated with this doclet. - @type Array. - */ - this.meta.range = meta.range.slice(0); - } - - if (meta.lineno) { - /** - The name of the file containing the code associated with this doclet. - @type string - */ - this.meta.filename = path.basename(meta.filename); - /** - The line number of the code associated with this doclet. - @type number - */ - this.meta.lineno = meta.lineno; - - var pathname = path.dirname(meta.filename); - if (pathname && pathname !== '.') { - this.meta.path = pathname; - } - } - - /** - Information about the code symbol. - @namespace - */ - this.meta.code = (this.meta.code || {}); - if (meta.id) { this.meta.code.id = meta.id; } - if (meta.code) { - if (meta.code.name) { - /** The name of the symbol in the source code. */ - this.meta.code.name = meta.code.name; - } - if (meta.code.type) { - /** The type of the symbol in the source code. */ - this.meta.code.type = meta.code.type; - } - if (meta.code.node) { - this.meta.code.node = meta.code.node; - } - if (meta.code.funcscope) { - this.meta.code.funcscope = meta.code.funcscope; - } - if (meta.code.value) { - /** The value of the symbol in the source code. */ - this.meta.code.value = meta.code.value; - } - if (meta.code.paramnames) { - this.meta.code.paramnames = meta.code.paramnames.concat([]); - } - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/fs.js b/rsc/scripts/jsdoc/lib/jsdoc/fs.js deleted file mode 100644 index ee365a8d..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/fs.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Extended version of the standard `fs` module. - * @module jsdoc/fs - */ - -var fs = exports.fs = require('fs'); -var vm = require('jsdoc/util/vm'); - -// export the VM-specific implementations of the extra methods -// TODO: document extra methods here -var extras = vm.getModule('fs'); -Object.keys(extras).forEach(function(extra) { - exports[extra] = extras[extra]; -}); diff --git a/rsc/scripts/jsdoc/lib/jsdoc/name.js b/rsc/scripts/jsdoc/lib/jsdoc/name.js deleted file mode 100644 index b3b97d4b..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/name.js +++ /dev/null @@ -1,258 +0,0 @@ -/** - A collection of functions relating to JSDoc symbol name manipulation. - @module jsdoc/name - @requires jsdoc/tag/dictionary - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var jsdoc = { - tagDictionary: require('jsdoc/tag/dictionary') -}; - -var puncToScope = { '.': 'static', '~': 'inner', '#': 'instance' }, - scopeToPunc = { 'static': '.', 'inner': '~', 'instance': '#' }; - -var DEFAULT_SCOPE = 'static'; - -/** - Resolves the longname, memberof, variation and name values of the given doclet. - @param {module:jsdoc/doclet.Doclet} doclet - */ -exports.resolve = function(doclet) { - var name = doclet.name, - memberof = doclet.memberof || '', - about = {}, - parentDoc; - - doclet.name = name = name? (''+name).replace(/(^|\.)prototype\.?/g, '#') : ''; - - // member of a var in an outer scope? - if (name && !memberof && doclet.meta.code && doclet.meta.code.funcscope) { - name = doclet.longname = doclet.meta.code.funcscope + '~' + name; - } - - if (memberof || doclet.forceMemberof) { // @memberof tag given - memberof = ('' || memberof).replace(/\.prototype\.?/g, '#'); - - // the name is a fullname, like @name foo.bar, @memberof foo - if (name && name.indexOf(memberof) === 0 && name !== memberof) { - about = exports.shorten(name, (doclet.forceMemberof ? memberof : undefined)); - } - // the name and memberof are identical and refer to a module, - // like @name module:foo, @memberof module:foo (probably a member like 'var exports') - else if (name && name === memberof && name.indexOf('module:') === 0) { - about = exports.shorten(name, (doclet.forceMemberof ? memberof : undefined)); - } - // the name and memberof are identical, like @name foo, @memberof foo - else if (name && name === memberof) { - doclet.scope = doclet.scope || DEFAULT_SCOPE; - name = memberof + scopeToPunc[doclet.scope] + name; - about = exports.shorten(name, (doclet.forceMemberof ? memberof : undefined)); - } - // like @memberof foo# or @memberof foo~ - else if (name && /([#.~])$/.test(memberof) ) { - about = exports.shorten(memberof + name, (doclet.forceMemberof ? memberof : undefined)); - } - else if (name && doclet.scope) { - about = exports.shorten(memberof + (scopeToPunc[doclet.scope] || '') + name, - (doclet.forceMemberof ? memberof : undefined)); - } - } - else { // no @memberof - about = exports.shorten(name); - } - - if (about.name) { - doclet.name = about.name; - } - - if (about.memberof) { - doclet.setMemberof(about.memberof); - } - - if (about.longname && !doclet.longname) { - doclet.setLongname(about.longname); - } - - if (doclet.scope === 'global') { // via @global tag? - doclet.setLongname(doclet.name); - delete doclet.memberof; - } - else if (about.scope) { - if (about.memberof === '') { // via @memberof ? - doclet.scope = 'global'; - } - else { - doclet.scope = puncToScope[about.scope]; - } - } - else { - if (doclet.name && doclet.memberof && !doclet.longname) { - if ( /^([#.~])/.test(doclet.name) ) { - doclet.scope = puncToScope[RegExp.$1]; - doclet.name = doclet.name.substr(1); - } - else { - doclet.scope = DEFAULT_SCOPE; - } - - doclet.setLongname(doclet.memberof + scopeToPunc[doclet.scope] + doclet.name); - } - } - - if (about.variation) { - doclet.variation = about.variation; - } -}; - -/** - @inner - @memberof module:jsdoc/name - @param {string} name - @param {string} kind - @returns {string} The name with unsafe names enclosed in quotes. - */ -function quoteUnsafe(name, kind) { // docspaced names may have unsafe characters which need to be quoted by us - if ( (jsdoc.tagDictionary.lookUp(kind).setsDocletDocspace) && /[^$_a-zA-Z0-9\/]/.test(name) ) { - if (!/^[a-z_$-\/]+:\"/i.test(name)) { - return '"' + name.replace(/\"/g, '"') + '"'; - } - } - - return name; -} - -RegExp.escape = RegExp.escape || function(str) { - var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\ - return str.replace(specials, "\\$&"); -}; - -/** - @method module:jsdoc/name.applyNamespace - @param {string} longname The full longname of the symbol. - @param {string} ns The namespace to be applied. - @returns {string} The longname with the namespace applied. - */ -exports.applyNamespace = function(longname, ns) { - var nameParts = exports.shorten(longname), - name = nameParts.name; - longname = nameParts.longname; - - if ( !/^[a-zA-Z]+?:.+$/i.test(name) ) { - longname = longname.replace( new RegExp(RegExp.escape(name)+'$'), ns + ':' + name ); - } - - return longname; -}; - -/** - Given a longname like "a.b#c(2)", slice it up into ["a.b", "#", 'c', '2'], - representing the memberof, the scope, the name, and variation. - @param {string} longname - @param {string} forcedMemberof - @returns {object} Representing the properties of the given name. - */ -exports.shorten = function(longname, forcedMemberof) { - // quoted strings in a longname are atomic, convert to tokens - var atoms = [], token; - - // handle quoted names like foo["bar"] or foo['bar'] - longname = longname.replace(/(\[?["'].+?["']\]?)/g, function($) { - var dot = ''; - if ( /^\[/.test($) ) { - dot = '.'; - $ = $.replace( /^\[/g, '' ).replace( /\]$/g, '' ); - } - - token = '@{' + atoms.length + '}@'; - atoms.push($); - - return dot + token; // foo["bar"] => foo.@{1}@ - }); - - var name = '', - scope = '', // ., ~, or # - memberof = '', - parts, - variation; - - longname = longname.replace( /\.prototype\.?/g, '#' ); - - if (typeof forcedMemberof !== 'undefined') { - name = longname.substr(forcedMemberof.length); - parts = forcedMemberof.match(/^(.*?)([#.~]?)$/); - - if (parts[1]) { memberof = parts[1] || forcedMemberof; } - if (parts[2]) { scope = parts[2]; } - } - else { - parts = longname? - (longname.match( /^(:?(.+)([#.~]))?(.+?)$/ ) || []).reverse() - : ['']; - - name = parts[0] || ''; // ensure name is always initialised to avoid error being thrown when calling replace on undefined [gh-24] - scope = parts[1] || ''; // ., ~, or # - memberof = parts[2] || ''; - } - - // like /** @name foo.bar(2) */ - if ( /(.+)\(([^)]+)\)$/.test(name) ) { - name = RegExp.$1, variation = RegExp.$2; - } - - //// restore quoted strings back again - var i = atoms.length; - while (i--) { - longname = longname.replace('@{'+i+'}@', atoms[i]); - memberof = memberof.replace('@{'+i+'}@', atoms[i]); - scope = scope.replace('@{'+i+'}@', atoms[i]); - name = name.replace('@{'+i+'}@', atoms[i]); - } - - //// - return {longname: longname, memberof: memberof, scope: scope, name: name, variation: variation}; -}; - -/** - Split a string that starts with a name and ends with a description, into its parts. - @param {string} nameDesc - @returns {object} Hash with "name" and "description" properties. - */ -exports.splitName = function(nameDesc) { - var name = '', - desc = '', - thisChar = '', - inQuote = false; - - for (var i = 0, len = nameDesc.length; i < len; i++) { - thisChar = nameDesc.charAt(i); - - if (thisChar === '\\') { - name += thisChar + nameDesc.charAt(++i); - continue; - } - - if (thisChar === '"') { - inQuote = !inQuote; - } - - if (inQuote) { - name += thisChar; - continue; - } - - if (!inQuote) { - if ( /\s/.test(thisChar) ) { - desc = nameDesc.substr(i); - desc = desc.replace(/^[\s\-\s]+/, '').trim(); - break; - } - else { - name += thisChar; - } - } - } - - return { name: name, description: desc }; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/opts/argparser.js b/rsc/scripts/jsdoc/lib/jsdoc/opts/argparser.js deleted file mode 100644 index 7e68580b..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/opts/argparser.js +++ /dev/null @@ -1,179 +0,0 @@ -/** - Parse the command line arguments. - @module jsdoc/opts/argparser - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var _ = require('underscore'); - -var hasOwnProp = Object.prototype.hasOwnProperty; - -/** - Create an instance of the parser. - @classdesc A parser to interpret the key-value pairs entered on the command - line. - @constructor - */ -var ArgParser = function() { - this._options = []; - this._shortNameIndex = {}; - this._longNameIndex = {}; -}; - -ArgParser.prototype._getOptionByShortName = function(name) { - if (hasOwnProp.call(this._shortNameIndex, name)) { - return this._options[this._shortNameIndex[name]]; - } - return null; -}; - -ArgParser.prototype._getOptionByLongName = function(name) { - if (hasOwnProp.call(this._longNameIndex, name)) { - return this._options[this._longNameIndex[name]]; - } - return null; -}; - -/** - * Provide information about a legal option. - * @param {character} shortName The short name of the option, entered like: -T. - * @param {string} longName The equivalent long name of the option, entered like: --test. - * @param {boolean} hasValue Does this option require a value? Like: -t templatename - * @param {string} helpText A brief description of the option. - * @param {boolean} [canHaveMultiple=false] Set to `true` if the option can be provided more than once. - * @param {function} [coercer] A function to coerce the given value to a specific type. - * @example - * myParser.addOption('t', 'template', true, 'The path to the template.'); - * myParser.addOption('h', 'help', false, 'Show the help message.'); - */ -ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText, canHaveMultiple, coercer) { - this._options.push({ - shortName: shortName, - longName: longName, - hasValue: hasValue, - helpText: helpText, - canHaveMultiple: (canHaveMultiple || false), - coercer: coercer - }); - - if (shortName) { - this._shortNameIndex[shortName] = this._options.length - 1; - } - if (longName) { - this._longNameIndex[longName] = this._options.length - 1; - } -}; - -/** - Generate a summary of all the options with corresponding help text. - @returns {string} - */ -ArgParser.prototype.help = function() { - var helpArr = ['OPTIONS:'], - option, optionHelp; - - for (var i = 0, leni = this._options.length; i < leni; i++) { - option = this._options[i]; - optionHelp = '\t'; - - if (option.shortName) { - optionHelp += '-' + option.shortName + (option.longName ? ', ' : ''); - } - - if (option.longName) { - optionHelp += '--' + option.longName; - } - - if (option.hasValue) { - optionHelp += ' '; - } - - optionHelp += '\t\t' + option.helpText; - helpArr.push(optionHelp); - } - - return helpArr.join('\n'); -}; - -/** - Get the options. - @param {Array.} args An array, like ['-x', 'hello'] - @param {Object} [defaults={}] An optional collection of default values. - @returns {Object} The keys will be the longNames, or the shortName if - no longName is defined for that option. The values will be the values - provided, or `true` if the option accepts no value. - */ -ArgParser.prototype.parse = function(args, defaults) { - var result = defaults && _.defaults({}, defaults) || {}; - - result._ = []; - for (var i = 0, leni = args.length; i < leni; i++) { - var arg = '' + args[i], - next = (i < leni-1)? '' + args[i+1] : null, - option, - shortName = null, - longName, - name, - value = null; - - // like -t - if (arg.charAt(0) === '-') { - - // like --template - if (arg.charAt(1) === '-') { - name = longName = arg.slice(2); - option = this._getOptionByLongName(longName); - } - else { - name = shortName = arg.slice(1); - option = this._getOptionByShortName(shortName); - } - - if (option === null) { - throw new Error( 'Unknown command line option found: ' + name ); - } - - if (option.hasValue) { - value = next; - i++; - - if (value === null || value.charAt(0) === '-') { - throw new Error( 'Command line option requires a value: ' + name ); - } - } - else { - value = true; - } - - if (option.longName && shortName) { - name = option.longName; - } - - if (typeof option.coercer === 'function') { - value = option.coercer(value); - } - - // Allow for multiple options of the same type to be present - if (option.canHaveMultiple && hasOwnProp.call(result, name)) { - var val = result[name]; - - if (val instanceof Array) { - val.push(value); - } else { - result[name] = [val, value]; - } - } - else { - result[name] = value; - } - } - else { - result._.push(arg); - } - } - - return result; -}; - -module.exports = ArgParser; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/opts/args.js b/rsc/scripts/jsdoc/lib/jsdoc/opts/args.js deleted file mode 100644 index ddc3e620..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/opts/args.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - @module jsdoc/opts/args - @requires jsdoc/opts/argparser - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var ArgParser = require('jsdoc/opts/argparser'), - argParser = new ArgParser(), - hasOwnProp = Object.prototype.hasOwnProperty, - ourOptions, - querystring = require('querystring'), - util = require('util'); - - -// cast strings to booleans or integers where appropriate -function castTypes(item) { - var result = item; - - switch (result) { - case 'true': - return true; - case 'false': - return false; - default: - // might be an integer - var integer = parseInt(result, 10); - if (String(integer) === result && integer !== 'NaN') { - return integer; - } else { - return result; - } - } -} - -// check for strings that we need to cast to other types -function fixTypes(item) { - var result = item; - - // recursively process arrays and objects - if ( util.isArray(result) ) { - for (var i = 0, l = result.length; i < l; i++) { - result[i] = fixTypes(result[i]); - } - } else if (typeof result === 'object') { - Object.keys(result).forEach(function(prop) { - result[prop] = fixTypes(result[prop]); - }); - } else { - result = castTypes(result); - } - - return result; -} - -function parseQuery(str) { - var result = querystring.parse(str); - - Object.keys(result).forEach(function(prop) { - result[prop] = fixTypes(result[prop]); - }); - - return result; -} - -argParser.addOption('t', 'template', true, 'The name of the template to use. Default: the "default" template'); -argParser.addOption('c', 'configure', true, 'The path to the configuration file. Default: jsdoc __dirname + /conf.json'); -argParser.addOption('e', 'encoding', true, 'Assume this encoding when reading all source files. Default: utf8'); -argParser.addOption('T', 'test', false, 'Run all tests and quit.'); -argParser.addOption('d', 'destination', true, 'The path to the output folder. Use "console" to dump data to the console. Default: ./out/'); -argParser.addOption('p', 'private', false, 'Display symbols marked with the @private tag. Default: false'); -argParser.addOption('r', 'recurse', false, 'Recurse into subdirectories when scanning for source code files.'); -argParser.addOption('l', 'lenient', false, 'Continue to generate output if a doclet is incomplete or contains errors. Default: false'); -argParser.addOption('h', 'help', false, 'Print this message and quit.'); -argParser.addOption('X', 'explain', false, 'Dump all found doclet internals to console and quit.'); -argParser.addOption('q', 'query', true, 'A query string to parse and store in env.opts.query. Example: foo=bar&baz=true', false, parseQuery); -argParser.addOption('u', 'tutorials', true, 'Directory in which JSDoc should search for tutorials.'); -argParser.addOption('v', 'version', false, 'Display the version number and quit.'); - -//TODO [-R, recurseonly] = a number representing the depth to recurse -//TODO [-f, filter] = a regex to filter on <-- this can be better defined in the configs? - -//Here are options specific to tests -argParser.addOption(null, 'verbose', false, 'Display verbose output for tests'); -argParser.addOption(null, 'match', true, 'Only run tests containing ', true); -argParser.addOption(null, 'nocolor', false, 'Do not use color in console output from tests'); - -/** - Set the options for this app. - @throws {Error} Illegal arguments will throw errors. - @param {string|String[]} args The command line arguments for this app. - */ -exports.parse = function(args) { - args = args || []; - - if (typeof args === 'string' || args.constructor === String) { - args = (''+args).split(/\s+/g); - } - - ourOptions = argParser.parse(args); - - return ourOptions; -}; - -/** - Display help message for options. - */ -exports.help = function() { - return argParser.help(); -}; - -/** - Get a named option. - @param {string} name The name of the option. - @return {string} The value associated with the given name. - *//** - Get all the options for this app. - @return {Object} A collection of key/values representing all the options. - */ -exports.get = function(name) { - if (typeof name === 'undefined') { - return ourOptions; - } - else { - return ourOptions[name]; - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/package.js b/rsc/scripts/jsdoc/lib/jsdoc/package.js deleted file mode 100644 index 9b9cf99d..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/package.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - @overview - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - @module jsdoc/package - @see http://wiki.commonjs.org/wiki/Packages/1.0 - */ - -/** - @class - @classdesc Represents a JavaScript package. - @param {string} json - The contents of package.json. - */ -exports.Package = function(json) { - json = json || "{}"; - - /** The source files associated with this package. - @type {Array} - */ - this.files = []; - - /** The kind of this package. - @readonly - @default - @type {string} - */ - this.kind = 'package'; - - json = JSON.parse(json); - - /** The name of this package. - This value is found in the package.json file passed in as a command line option. - @type {string} - */ - this.name = json.name; - - /** The longname of this package. - @type {string} - */ - this.longname = this.kind + ':' + this.name; - - /** The description of this package. - @type {string} - */ - this.description = json.description; - - /** - The hash summary of the source file. - @type {string} - @since 3.2.0 - */ - this.version = json.version; - - /** - * The licenses of this package. - * @type {Array} - * @example - * "licenses": [ - * { - * "type": "GPLv2", - * "url": "http://www.example.com/licenses/gpl.html" - * } - * ] - */ - this.licenses = json.licenses; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/path.js b/rsc/scripts/jsdoc/lib/jsdoc/path.js deleted file mode 100644 index 4ddb031d..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/path.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Extended version of the standard `path` module. - * @module jsdoc/path - */ - -var fs = require('fs'); -var path = require('path'); -var vm = require('jsdoc/util/vm'); - - -function prefixReducer(previousPath, current) { - var currentPath = []; - - // if previousPath is defined, but has zero length, there's no common prefix; move along - if (previousPath && !previousPath.length) { - return currentPath; - } - - currentPath = path.resolve( process.cwd(), path.dirname(current) ).split(path.sep) || []; - - if (previousPath && currentPath.length) { - // remove chunks that exceed the previous path's length - currentPath = currentPath.slice(0, previousPath.length); - - // if a chunk doesn't match the previous path, remove everything from that chunk on - for (var i = 0, l = currentPath.length; i < l; i++) { - if (currentPath[i] !== previousPath[i]) { - currentPath.splice(i, currentPath.length - i); - break; - } - } - } - - return currentPath; -} - -/** - * Find the common prefix for an array of paths. If there is a common prefix, a trailing separator - * is appended to the prefix. Relative paths are resolved relative to the current working directory. - * - * For example, assuming that the current working directory is `/Users/jsdoc`: - * - * + For paths `foo/bar/baz/qux.js`, `foo/bar/baz/quux.js`, and `foo/bar/baz.js`, the common prefix - * is `/Users/jsdoc/foo/bar/`. - * + For paths `../jsdoc/foo/bar/baz/qux/quux/test.js`, `/Users/jsdoc/foo/bar/bazzy.js`, and - * `../../Users/jsdoc/foo/bar/foobar.js`, the common prefix is `/Users/jsdoc/foo/bar/`. - * + For paths `foo/bar/baz/qux.js` and `../../Library/foo/bar/baz.js`, there is no common prefix, - * and an empty string is returned. - * - * @param {Array.} paths - The paths to search for a common prefix. - * @return {string} The common prefix, or an empty string if there is no common prefix. - */ -exports.commonPrefix = function(paths) { - var common = paths.reduce(prefixReducer, undefined); - - // if there's anything left (other than a placeholder for a leading slash), add a placeholder - // for a trailing slash - if ( common.length && (common.length > 1 || common[0] !== '') ) { - common.push(''); - } - - return common.join(path.sep); -}; - -// TODO: do we need this? -/** - * If required by the current VM, convert a path to a URI that meets the operating system's - * requirements. Otherwise, return the original path. - * @function - * @private - * @param {string} path The path to convert. - * @return {string} A URI that meets the operating system's requirements, or the original path. - */ -var pathToUri = vm.getModule('jsdoc').pathToUri; - -// TODO: do we need this? if so, any way to stop exporting it? -/** - * If required by the current VM, convert a URI to a path that meets the operating system's - * requirements. Otherwise, assume the "URI" is really a path, and return the original path. - * @function - * @private - * @param {string} uri The URI to convert. - * @return {string} A path that meets the operating system's requirements. - */ -exports._uriToPath = vm.getModule('jsdoc').uriToPath; - -/** - * Retrieve the fully qualified path to the requested resource. - * - * If the resource path is specified as a relative path, JSDoc searches for the path in the current - * working directory, then in the JSDoc directory. - * - * If the resource path is specified as a fully qualified path, JSDoc uses the path as-is. - * - * @param {string} filepath - The path to the requested resource. May be an absolute path; a path - * relative to the JSDoc directory; or a path relative to the current working directory. - * @param {string} [filename] - The filename of the requested resource. - * @return {string} The fully qualified path (or, on Rhino, a URI) to the requested resource. - * Includes the filename if one was provided. - */ -exports.getResourcePath = function(filepath, filename) { - var result; - - function pathExists(_path) { - try { - fs.readdirSync(_path); - } - catch(e) { - return false; - } - - return true; - } - - // first, try resolving it relative to the current working directory (or just normalize it - // if it's an absolute path) - result = path.resolve(filepath); - if ( !pathExists(result) ) { - // next, try resolving it relative to the JSDoc directory - result = path.resolve(__dirname, filepath); - if ( !pathExists(result) ) { - result = null; - } - } - - if (result) { - result = filename ? path.join(result, filename) : result; - result = pathToUri(result); - } - - return result; -}; - -Object.keys(path).forEach(function(member) { - exports[member] = path[member]; -}); diff --git a/rsc/scripts/jsdoc/lib/jsdoc/plugins.js b/rsc/scripts/jsdoc/lib/jsdoc/plugins.js deleted file mode 100644 index 5e2637bc..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/plugins.js +++ /dev/null @@ -1,45 +0,0 @@ -/*global app: true */ -/** - * Utility functions to support the JSDoc plugin framework. - * @module jsdoc/plugins - */ - -var error = require('jsdoc/util/error'); -var path = require('jsdoc/path'); - -exports.installPlugins = function(plugins, p) { - var dictionary = require('jsdoc/tag/dictionary'); - var parser = p; - - var eventName; - var plugin; - var pluginPath; - - for (var i = 0, l = plugins.length; i < l; i++) { - pluginPath = path.getResourcePath(path.dirname(plugins[i]), path.basename(plugins[i])); - if (!pluginPath) { - error.handle(new Error('Unable to find the plugin "' + plugins[i] + '"')); - } - else { - plugin = require(pluginPath); - - // allow user-defined plugins to... - //...register event handlers - if (plugin.handlers) { - Object.keys(plugin.handlers).forEach(function(eventName) { - parser.on(eventName, plugin.handlers[eventName]); - }); - } - - //...define tags - if (plugin.defineTags) { - plugin.defineTags(dictionary); - } - - //...add a node visitor - if (plugin.nodeVisitor) { - parser.addNodeVisitor(plugin.nodeVisitor); - } - } - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/readme.js b/rsc/scripts/jsdoc/lib/jsdoc/readme.js deleted file mode 100644 index 0e3ca21e..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/readme.js +++ /dev/null @@ -1,25 +0,0 @@ -/*global env: true */ - -/** - * Make the contents of a README file available to include in the output. - * @module jsdoc/readme - * @author Michael Mathews - * @author Ben Blank - */ - -var fs = require('jsdoc/fs'), - markdown = require('jsdoc/util/markdown'); - -/** - * @class - * @classdesc Represents a README file. - * @param {string} path - The filepath to the README. - */ -function ReadMe(path) { - var content = fs.readFileSync(path, env.opts.encoding), - parse = markdown.getParser(); - - this.html = parse(content); -} - -module.exports = ReadMe; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/schema.js b/rsc/scripts/jsdoc/lib/jsdoc/schema.js deleted file mode 100644 index 2fa32dde..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/schema.js +++ /dev/null @@ -1,308 +0,0 @@ -/** - @overview Schema for validating JSON produced by JSDoc Toolkit. - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - @see - */ - -exports.jsdocSchema = { - "properties": { - "doc": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "author": { - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "path": { // unique identifier for each doc - "type": "string", - "maxItems": 1 - }, - "description": { // a description - "type": "string", - "optional": true, - "maxItems": 1 - }, - "classdesc": { // a description of the class that this constructor belongs to - "type": "string", - "optional": true, - "maxItems": 1 - }, - "name": { // probably a trailing substring of the path - "type": "string", - "maxItems": 1 - }, - "version": { // what is the version of this doc - "type": "string", - "optional": true, - "maxItems": 1 - }, - "since": { // at what previous version was this doc added? - "type": "string", - "optional": true, - "maxItems": 1 - }, - "see": { // some thing else to consider - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "tutorials": { // extended tutorials - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "deprecated": { // is usage of this symbol deprecated? - "type": ["string", "boolean"], - "optional": true - }, - "scope": { // how is this symbol attached to it's enclosing scope? - "type": "string", - "maxItems": 1, - "enum": ["global", "static", "instance", "inner"] - }, - "memberof": { // probably a leading substring of the path - "type": "string", - "optional": true, - "maxItems": 1 - }, - "extends": { // the path to another constructor - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "fires": { // the path to another doc object - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "requires": { // the symbol being documented requires another symbol - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "implements": { - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "kind": { // what kind of symbol is this? - "type": "string", - "maxItems": 1, - "enum": ["constructor", "module", "event", "namespace", "method", "member", "enum", "class", "interface", "constant", "mixin", "file", "version"] - }, - "refersto": { // the path to another doc: this doc is simply a renamed alias to that - "type": "string", - "optional": true, - "maxItems": 1 - }, - "access": { // what access priviledges are allowed - "type": "string", - "optional": true, - "maxItems": 1, - "enum": ["private", "protected", "public"] - }, - "virtual": { // is a member left to be implemented during inheritance? - "type": "boolean", - "optional": true, - "default": false - }, - "attrib": { // other attributes, like "readonly" - "type": "string", - "optional": true - }, - "type": { // what type is the value that this doc is associated with, like "number" - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "exception" : { - "optional": true, - "type": "object", - "properties": { - "type": { // what is the type of the value thrown? - "type": "array", - "optional": true, - "items": { - "type": "string" - } - }, - "description": { // a description of the thrown value - "type": "string", - "optional": true - } - }, - "additionalProperties": false - }, - "returns" : { - "optional": true, - "type": "object", - "properties": { - "type": { // what is the type of the value returned? - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "description": { // a description of the returned value - "type": "string", - "optional": true - } - }, - "additionalProperties": false - }, - "param" : { // are there function parameters associated with this doc? - "type": "array", - "optional": true, - "items": { - "type": "object", - "properties": { - "type": { // what are the types of value expected for this parameter? - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "optional": { // is a value for this parameter optional? - "type": "boolean", - "optional": true, - "default": true - }, - "nullable": { // can the value for this parameter be null? - "type": "boolean", - "optional": true, - "default": true - }, - "defaultvalue": { // what is the default value for this parameter? - "type": "string", - "optional": true - }, - "name": { // what name does this parameter have within the function? - "type": "string" - }, - "description": { // a description of the parameter - "type": "string", - "optional": true - } - }, - "additionalProperties": false - } - }, - "thisobj": { - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "example": { // some thing else to consider - "type": ["string", "array"], - "optional": true, - "items": { - "type": "string" - } - }, - "tags": { // arbitrary tags associated with this doc - "type": "array", - "optional": true, - "additionalProperties": false, - "items": { - "type": "string" - } - }, - "meta": { // information about this doc - "type": "object", - "optional": true, - "maxItems": 1, - "properties": { - "file": { // what is the name of the file this doc appears in? - "type": "string", - "optional": true, - "maxItems": 1 - }, - "line": { // on what line of the file does this doc appear? - "type": "number", - "optional": true, - "maxItems": 1 - } - }, - "additionalProperties": false - } - } - } - }, - "meta": { // information about the generation for all the docs - "type": "object", - "optional": true, - "maxItems": 1, - "properties": { - "project": { // to what project does this doc belong? - "type": "object", - "optional": true, - "maxItems": 1, - "properties": { - "name": { // the name of the project - "type": "string", - "maxItems": 1 - }, - "uri": { // the URI of the project - "type": "string", - "maxItems": 1, - "format": "uri" - }, - "version": { // the version of the project - "type": "string", - "maxItems": 1 - }, - "lang": { // the programming language used in the project - "type": "string", - "maxItems": 1 - } - }, - "additionalProperties": false - }, - "generated": { // some information about the running of the doc generator - "type": "object", - "optional": true, - "maxItems": 1, - "properties": { - "date": { // on what date and time was the doc generated? - "type": "string", - "maxItems": 1, - "optional": true, - "format": "date-time" - }, - "parser": { // what tool was used to generate the doc? - "type": "string", - "maxItems": 1, - "optional": true - } - }, - "additionalProperties": false - } - } - } - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/lib/jsdoc/src/filter.js b/rsc/scripts/jsdoc/lib/jsdoc/src/filter.js deleted file mode 100644 index 4bd18055..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/src/filter.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - @module jsdoc/src/filter - - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var path = require('jsdoc/path'); - -/** - @constructor - @param {object} opts - @param {string[]} opts.exclude - Specific files to exclude. - @param {string|RegExp} opts.includePattern - @param {string|RegExp} opts.excludePattern - */ -exports.Filter = function(opts) { - var cwd = process.cwd(); - - this.exclude = opts.exclude && Array.isArray(opts.exclude) ? - opts.exclude.map(function($) { - return path.resolve(cwd, $); - }) : - null; - this.includePattern = opts.includePattern? - typeof opts.includePattern === 'string'? new RegExp(opts.includePattern) : opts.includePattern - : null; - this.excludePattern = opts.excludePattern? - typeof opts.excludePattern === 'string'? new RegExp(opts.excludePattern) : opts.excludePattern - : null; -}; - -/** - @param {string} filepath - The filepath to check. - @returns {boolean} Should the given file be included? - */ -exports.Filter.prototype.isIncluded = function(filepath) { - filepath = path.resolve(process.cwd(), filepath); - - if ( this.includePattern && !this.includePattern.test(filepath) ) { - return false; - } - - if ( this.excludePattern && this.excludePattern.test(filepath) ) { - return false; - } - - if ( this.exclude && this.exclude.indexOf(filepath) > -1 ) { - return false; - } - - return true; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/src/handlers.js b/rsc/scripts/jsdoc/lib/jsdoc/src/handlers.js deleted file mode 100644 index fef4bf13..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/src/handlers.js +++ /dev/null @@ -1,200 +0,0 @@ -/** - * @module jsdoc/src/handlers - */ - - -var currentModule = null; - -function getNewDoclet(comment, e) { - var jsdoc = {doclet: require('jsdoc/doclet')}; - var util = require('util'); - var err; - - try { - return new jsdoc.doclet.Doclet(comment, e); - } - catch (error) { - err = new Error( util.format('cannot create a doclet for the comment "%s": %s', - comment.replace(/[\r\n]/g, ''), error.message) ); - require('jsdoc/util/error').handle(err); - return new jsdoc.doclet.Doclet('', {}); - } -} - -/** - * Attach these event handlers to a particular instance of a parser. - * @param parser - */ -exports.attachTo = function(parser) { - var jsdoc = {doclet: require('jsdoc/doclet'), name: require('jsdoc/name')}; - - // handles JSDoc comments that include a @name tag -- the code is ignored in such a case - parser.on('jsdocCommentFound', function(e) { - var newDoclet = getNewDoclet(e.comment, e); - - if (!newDoclet.name) { - return false; // only interested in virtual comments (with a @name) here - } - - addDoclet.call(this, newDoclet); - if (newDoclet.kind === 'module') { - currentModule = newDoclet.longname; - } - e.doclet = newDoclet; - - //resolveProperties(newDoclet); - }); - - // handles named symbols in the code, may or may not have a JSDoc comment attached - parser.on('symbolFound', function(e) { - var subDoclets = e.comment.split(/@also\b/g); - - for (var i = 0, l = subDoclets.length; i < l; i++) { - newSymbolDoclet.call(this, subDoclets[i], e); - } - }); - - // TODO: for clarity, decompose into smaller functions - function newSymbolDoclet(docletSrc, e) { - var memberofName = null, - newDoclet = getNewDoclet(docletSrc, e); - - // an undocumented symbol right after a virtual comment? rhino mistakenly connected the two - if (newDoclet.name) { // there was a @name in comment - // try again, without the comment - e.comment = '@undocumented'; - newDoclet = getNewDoclet(e.comment, e); - } - - if (newDoclet.alias) { - if (newDoclet.alias === '{@thisClass}') { - memberofName = this.resolveThis(e.astnode); - - // "class" refers to the owner of the prototype, not the prototype itself - if ( /^(.+?)(\.prototype|#)$/.test(memberofName) ) { - memberofName = RegExp.$1; - } - newDoclet.alias = memberofName; - } - newDoclet.addTag('name', newDoclet.alias); - newDoclet.postProcess(); - } - else if (e.code && e.code.name) { // we need to get the symbol name from code - newDoclet.addTag('name', e.code.name); - if (!newDoclet.memberof && e.astnode) { - var basename = null, - scope = ''; - if ( /^((module.)?exports|this)(\.|$)/.test(newDoclet.name) ) { - var nameStartsWith = RegExp.$1; - - newDoclet.name = newDoclet.name.replace(/^(exports|this)(\.|$)/, ''); - - // like /** @module foo */ exports.bar = 1; - if (nameStartsWith === 'exports' && currentModule) { - memberofName = currentModule; - scope = 'static'; - } - else if (newDoclet.name === 'module.exports' && currentModule) { - newDoclet.addTag('name', currentModule); - newDoclet.postProcess(); - } - else { - // like /** @module foo */ exports = {bar: 1}; - // or /** blah */ this.foo = 1; - memberofName = this.resolveThis(e.astnode); - scope = nameStartsWith === 'exports'? 'static' : 'instance'; - - // like /** @module foo */ this.bar = 1; - if (nameStartsWith === 'this' && currentModule && !memberofName) { - memberofName = currentModule; - scope = 'static'; - } - } - - if (memberofName) { - if (newDoclet.name) { - newDoclet.name = memberofName + (scope === 'instance'? '#' : '.') + newDoclet.name; - } - else { newDoclet.name = memberofName; } - } - } - else { - memberofName = this.astnodeToMemberof(e.astnode); - if( Array.isArray(memberofName) ) { - basename = memberofName[1]; - memberofName = memberofName[0]; - } - } - - if (memberofName) { - newDoclet.addTag('memberof', memberofName); - if (basename) { - newDoclet.name = newDoclet.name.replace(new RegExp('^' + RegExp.escape(basename) + '.'), ''); - } - } - else { - // add @inner and @memberof tags unless the current module exports only this symbol - if (currentModule && currentModule !== newDoclet.name) { - // add @inner unless the current module exports only this symbol - if (!newDoclet.scope) { - newDoclet.addTag('inner'); - } - - if (!newDoclet.memberof && newDoclet.scope !== 'global') { - newDoclet.addTag('memberof', currentModule); - } - } - } - } - - newDoclet.postProcess(); - } - else { - return false; - } - - //resolveProperties(newDoclet); - - // set the scope to global unless a) the doclet is a memberof something or b) the current - // module exports only this symbol - if (!newDoclet.memberof && currentModule !== newDoclet.name) { - newDoclet.scope = 'global'; - } - - addDoclet.call(this, newDoclet); - e.doclet = newDoclet; - } - - //parser.on('fileBegin', function(e) { }); - - parser.on('fileComplete', function(e) { - currentModule = null; - }); - - function addDoclet(newDoclet) { - var e; - if (newDoclet) { - e = { doclet: newDoclet }; - this.emit('newDoclet', e); - - if ( !e.defaultPrevented && !filter(newDoclet) ) { - this.addResult(newDoclet); - } - } - } - - function filter(doclet) { - // you can't document prototypes - if ( /#$/.test(doclet.longname) ) { - return true; - } - // you can't document symbols added by the parser with a dummy name - if (doclet.meta.code && doclet.meta.code.name === '____') { - return true; - } - - return false; - } - - function resolveProperties(newDoclet) {} -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/src/parser.js b/rsc/scripts/jsdoc/lib/jsdoc/src/parser.js deleted file mode 100644 index d98b0829..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/src/parser.js +++ /dev/null @@ -1,779 +0,0 @@ -/*global env: true, Packages: true */ -/** - * @module jsdoc/src/parser - * @requires fs - * @requires events - */ - -var Token = Packages.org.mozilla.javascript.Token; -var hasOwnProp = Object.prototype.hasOwnProperty; - -/** - * @class - * @mixes module:events - * - * @example Create a new parser. - * var jsdocParser = new (require('jsdoc/src/parser').Parser)(); - */ -exports.Parser = function() { - this._currentSourceName = ''; - this._resultBuffer = []; - this._comments = { - original: [], - modified: [] - }; - //Initialize a global ref to store global members - this.refs = { - __global__: { - meta: {} - } - }; - this._visitors = []; -}; -exports.Parser.prototype = Object.create( require('events').EventEmitter.prototype ); - -/** - * Parse the given source files for JSDoc comments. - * @param {Array.} sourceFiles An array of filepaths to the JavaScript sources. - * @param {string} [encoding=utf8] - * - * @fires jsdocCommentFound - * @fires symbolFound - * @fires newDoclet - * @fires fileBegin - * @fires fileComplete - * - * @example Parse two source files. - * var myFiles = ['file1.js', 'file2.js']; - * var docs = jsdocParser.parse(myFiles); - */ -exports.Parser.prototype.parse = function(sourceFiles, encoding) { - encoding = encoding || env.conf.encoding || 'utf8'; - - const SCHEMA = 'javascript:'; - - var filename = ''; - var sourceCode = ''; - var parsedFiles = []; - var e = {}; - - if (typeof sourceFiles === 'string') { - sourceFiles = [sourceFiles]; - } - - e.sourcefiles = sourceFiles; - - this.emit('parseBegin', e); - - for (var i = 0, l = sourceFiles.length; i < l; i++) { - sourceCode = ''; - - if (sourceFiles[i].indexOf(SCHEMA) === 0) { - sourceCode = sourceFiles[i].substr(SCHEMA.length); - filename = '[[string' + i + ']]'; - } - else { - filename = sourceFiles[i]; - try { - sourceCode = require('jsdoc/fs').readFileSync(filename, encoding); - } - catch(e) { - console.log('FILE READ ERROR: in module:jsdoc/parser.parseFiles: "' + filename + - '" ' + e); - continue; - } - } - - if (sourceCode.length) { - this._parseSourceCode(sourceCode, filename); - parsedFiles.push(filename); - } - } - - this.emit('parseComplete', { - sourcefiles: parsedFiles - }); - - return this._resultBuffer; -}; - -/** - * @returns {Array} The accumulated results of any calls to parse. - */ -exports.Parser.prototype.results = function() { - return this._resultBuffer; -}; - -/** - * @param {Object} o The parse result to add to the result buffer. - */ -exports.Parser.prototype.addResult = function(o) { - this._resultBuffer.push(o); -}; - -/** - * Empty any accumulated results of calls to parse. - */ -exports.Parser.prototype.clear = function() { - this._currentSourceName = ''; - this._resultBuffer = []; - this._comments = { - original: [], - modified: [] - }; -}; - -/** - * Adds a node visitor to use in parsing - */ -exports.Parser.prototype.addNodeVisitor = function(visitor) { - this._visitors.push(visitor); -}; - -/** - * Get the node visitors used in parsing - */ -exports.Parser.prototype.getVisitors = function() { - return this._visitors; -}; - -function pretreat(code) { - return code - // make starbangstar comments look like real jsdoc comments - .replace(/\/\*\!\*/g, '/**') - - // merge adjacent doclets - .replace(/\*\/\/\*\*+/g, '@also') - // make lent object literals documentable by giving them a dummy name - // like return @lends { - .replace(/(\/\*\*[^\*\/]*?[\*\s]*@lends\s(?:[^\*]|\*(?!\/))*\*\/\s*)\{/g, '$1 ____ = {') - // like @lends return { - .replace(/(\/\*\*[^\*\/]*?@lends\b[^\*\/]*?\*\/)(\s*)return(\s*)\{/g, - '$2$3 return $1 ____ = {'); -} - -var tkn = { - NAMEDFUNCTIONSTATEMENT: -1001 -}; -exports.Parser.tkn = tkn; - -/** @private */ -function parserFactory() { - var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); - - var ce = new Packages.org.mozilla.javascript.CompilerEnvirons(); - ce.setRecordingComments(true); - ce.setRecordingLocalJsDocComments(true); - ce.setLanguageVersion(180); - - ce.initFromContext(cx); - return new Packages.org.mozilla.javascript.Parser(ce, ce.getErrorReporter()); -} - -/** @private - @memberof module:src/parser.Parser -*/ -function getTypeName(node) { - var type = ''; - - if (node) { - type = '' + Packages.org.mozilla.javascript.Token.typeToName(node.getType()); - } - - return type; -} - -/** @private - @memberof module:src/parser.Parser -*/ -function nodeToString(node) { - var str; - - if (!node) { - return; - } - - if (node.type === Token.GETPROP) { - str = [nodeToString(node.target), node.property.string].join('.'); - } - else if (node.type === Token.VAR) { - str = nodeToString(node.target); - } - else if (node.type === Token.NAME) { - str = node.string; - } - else if (node.type === Token.STRING) { - str = node.value; - } - else if (node.type === Token.NUMBER) { - str = node.value; - } - else if (node.type === Token.THIS) { - str = 'this'; - } - else if (node.type === Token.GETELEM) { - str = node.toSource(); // like: Foo['Bar'] - } - else if (node.type === Token.NEG || node.type === Token.TRUE || node.type === Token.FALSE) { - str = node.toSource(); // like -1 - } - else { - str = getTypeName(node); - } - - return '' + str; -} - -/** - * Attempts to find the name and type of the given node. - * @private - * @memberof module:src/parser.Parser - */ -function aboutNode(node) { - var about = {}; - - if (node.type == Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) { - about.name = node.type == tkn.NAMEDFUNCTIONSTATEMENT? '' : '' + node.name; - about.type = 'function'; - about.node = node; - } - else if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) { - about.name = nodeToString(node.target); - if (node.initializer) { // like var i = 0; - about.node = node.initializer; - about.value = nodeToString(about.node); - about.type = getTypeName(node.initializer); - if (about.type === 'FUNCTION' && about.node.name) { - about.node.type = tkn.NAMEDFUNCTIONSTATEMENT; - } - } - else { // like var i; - about.node = node.target; - about.value = nodeToString(about.node); - about.type = 'undefined'; - } - } - else if (node.type === Token.ASSIGN || node.type === Token.COLON || - node.type === Token.GET || node.type === Token.SET) { - about.name = nodeToString(node.left); - if (node.type === Token.COLON) { - - // objlit keys with unsafe variable-name characters must be quoted - if (!/^[$_a-z][$_a-z0-9]*$/i.test(about.name) ) { - about.name = '"'+about.name.replace(/"/g, '\\"')+'"'; - } - } - about.node = node.right; - about.value = nodeToString(about.node); - - // Getter and setter functions should be treated as properties - if (node.type === Token.GET || node.type === Token.SET) { - about.type = getTypeName(node); - } else { - about.type = getTypeName(node.right); - } - - if (about.type === 'FUNCTION' && about.node.name) { - about.node.type = tkn.NAMEDFUNCTIONSTATEMENT; - } - } - else if (node.type === Token.GETPROP) { - about.node = node; - about.name = nodeToString(about.node); - about.type = getTypeName(node); - } - else { - // type 39 (NAME) - var string = nodeToString(node); - if (string) { - about.name = string; - } - } - - // get names of the formal parameters declared for this function - if (about.node && about.node.getParamCount) { - var paramCount = about.node.getParamCount(); - if (typeof paramCount === 'number') { - about.node.flattenSymbolTable(true); - var paramNames = []; - for (var i = 0, l = paramCount; i < l; i++) { - paramNames.push( '' + about.node.getParamOrVarName(i) ); - } - about.paramnames = paramNames; - } - } - - return about; -} - -/** @private - @memberof module:src/parser.Parser -*/ -function isValidJsdoc(commentSrc) { - /*** ignore comments that start with many stars ***/ - return commentSrc && commentSrc.indexOf('/***') !== 0; -} - -/** @private - * @memberof module:src/parser.Parser - */ -function makeVarsFinisher(funcDoc) { - return function(e) { - //no need to evaluate all things related to funcDoc again, just use it - if (funcDoc && e.doclet && e.doclet.alias) { - funcDoc.meta.vars[e.code.name] = e.doclet.longname; - } - }; -} - -/** @private - * @memberof module:src/parser.Parser - * @param {string} name Full symbol name. - * @return {string} Basename. - */ -function getBasename(name) { - if (name !== undefined) { - return name.replace(/^([$a-z_][$a-z_0-9]*).*?$/i, '$1'); - } - return name; -} - -/** @private - * @memberof module:src/parser.Parser - * @param {object} node - * @return {Array.} Start and end lines. - */ -function getRange(node) { - var range = []; - - range[0] = parseInt(String(node.getAbsolutePosition()), 10); - range[1] = range[0] + parseInt(String(node.getLength()), 10); - - return range; -} - -/** @private - * @memberof module:src/parser.Parser - */ -exports.Parser.prototype._makeEvent = function(node, extras) { - extras = extras || {}; - - // fill in default values as needed. if we're overriding a property, don't execute the default - // code for that property, since it might blow up. - var result = { - id: extras.id || 'astnode' + node.hashCode(), - comment: extras.comment || String(node.getJsDoc() || '@undocumented'), - lineno: extras.lineno || node.left.getLineno(), - range: extras.range || getRange(node), - filename: extras.filename || this._currentSourceName, - astnode: extras.astnode || node, - code: extras.code || aboutNode(node), - event: extras.event || 'symbolFound', - finishers: extras.finishers || [this.addDocletRef] - }; - - // use the modified version of the comment - var idx = this._comments.original.indexOf(result.comment); - if (idx !== -1) { - result.comment = this._comments.modified[idx]; - } - - // make sure the result includes extras that don't have default values - Object.keys(extras).forEach(function(prop) { - result[prop] = extras[prop]; - }); - - return result; -}; - -/** @private - * @memberof module:src/parser.Parser - */ -exports.Parser.prototype._trackVars = function(node, e) { - // keep track of vars in a function or global scope - var func = '__global__'; - var funcDoc = null; - - if (node.enclosingFunction) { - func = 'astnode' + node.enclosingFunction.hashCode(); - } - - funcDoc = this.refs[func]; - if (funcDoc) { - funcDoc.meta.vars = funcDoc.meta.vars || {}; - funcDoc.meta.vars[e.code.name] = false; - e.finishers.push(makeVarsFinisher(funcDoc)); - } -}; - -/** @private */ -exports.Parser.prototype._visitComment = function(comment) { - var e; - var original = String( comment.toSource() ); - var modified; - - if ( original && isValidJsdoc(original) ) { - this._comments.original.push(original); - - e = { - comment: original, - lineno: comment.getLineno(), - filename: this._currentSourceName, - range: getRange(comment) - }; - - this.emit('jsdocCommentFound', e, this); - - if (e.comment !== original) { - modified = e.comment; - } - - this._comments.modified.push(modified || original); - } - - return true; -}; - -/** @private */ -exports.Parser.prototype._visitNode = function(node) { - var e, - extras, - basename, - func, - funcDoc, - i, - l; - - if (node.type === Token.ASSIGN) { - e = this._makeEvent(node); - - basename = getBasename(e.code.name); - - if (basename !== 'this') { - e.code.funcscope = this.resolveVar(node, basename); - } - } - else if (node.type === Token.COLON) { // assignment within an object literal - extras = { - comment: String(node.left.getJsDoc() || '@undocumented'), - finishers: [this.addDocletRef, this.resolveEnum] - }; - e = this._makeEvent(node, extras); - } - else if (node.type === Token.GET || node.type === Token.SET) { // assignment within an object literal - extras = { - comment: String(node.left.getJsDoc() || '@undocumented') - }; - e = this._makeEvent(node, extras); - } - else if (node.type === Token.GETPROP) { // like 'obj.prop' in '/** @typedef {string} */ obj.prop;' - // this COULD be a Closure Compiler-style typedef, but it's probably not; to avoid filling - // the parse results with junk, only fire an event if there's a JSDoc comment attached - extras = { - lineno: node.getLineno() - }; - if ( node.getJsDoc() ) { - e = this._makeEvent(node, extras); - } - } - else if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) { - - if (node.variables) { - return true; // we'll get each var separately on future visits - } - - if (node.parent.variables.toArray()[0] === node) { // like /** blah */ var a=1, b=2, c=3; - // the first var assignment gets any jsDoc before the whole var series - if (typeof node.setJsDoc !== 'undefined') { node.setJsDoc( node.parent.getJsDoc() ); } - } - - extras = { - lineno: node.getLineno() - }; - e = this._makeEvent(node, extras); - - this._trackVars(node, e); - } - else if (node.type == Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) { - extras = { - lineno: node.getLineno() - }; - e = this._makeEvent(node, extras); - - e.code.name = (node.type == tkn.NAMEDFUNCTIONSTATEMENT)? '' : String(node.name) || ''; - - this._trackVars(node, e); - - basename = getBasename(e.code.name); - e.code.funcscope = this.resolveVar(node, basename); - } - - if (!e) { - e = { - finishers: [] - }; - } - - for (i = 0, l = this._visitors.length; i < l; i++) { - this._visitors[i].visitNode(node, e, this, this._currentSourceName); - if (e.stopPropagation) { break; } - } - - if (!e.preventDefault && isValidJsdoc(e.comment)) { - this.emit(e.event, e, this); - } - - for (i = 0, l = e.finishers.length; i < l; i++) { - e.finishers[i].call(this, e); - } - - return true; -}; - -/** @private */ -exports.Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { - var NodeVisitor = Packages.org.mozilla.javascript.ast.NodeVisitor; - - var ast; - var e = { - filename: sourceName - }; - - this.emit('fileBegin', e); - - if (!e.defaultPrevented) { - e = { - filename: sourceName, - source: sourceCode - }; - this.emit('beforeParse', e); - sourceCode = e.source; - this._currentSourceName = sourceName = e.filename; - - sourceCode = pretreat(e.source); - - ast = parserFactory().parse(sourceCode, sourceName, 1); - - ast.visitComments( - new NodeVisitor({ - visit: this._visitComment.bind(this) - }) - ); - - ast.visit( - new NodeVisitor({ - visit: this._visitNode.bind(this) - }) - ); - } - - this.emit('fileComplete', e); - - this._currentSourceName = ''; -}; - -/** - * Given a node, determine what the node is a member of. - * @param {astnode} node - * @returns {string} The long name of the node that this is a member of. - */ -exports.Parser.prototype.astnodeToMemberof = function(node) { - var id, - doclet, - alias; - - if (node.type === Token.VAR || node.type === Token.FUNCTION || - node.type == tkn.NAMEDFUNCTIONSTATEMENT) { - if (node.enclosingFunction) { // an inner var or func - id = 'astnode' + node.enclosingFunction.hashCode(); - doclet = this.refs[id]; - if (!doclet) { - return '~'; - } - return (doclet.longname || doclet.name) + '~'; - } - } - else { - // check local references for aliases - var scope = node, - basename = getBasename(nodeToString(node.left)); - while(scope.enclosingFunction) { - id = 'astnode' + scope.enclosingFunction.hashCode(); - doclet = this.refs[id]; - if ( doclet && doclet.meta.vars && hasOwnProp.call(doclet.meta.vars, basename) ) { - return [doclet.meta.vars[basename], basename]; - } - // move up - scope = scope.enclosingFunction; - } - // First check to see if we have a global scope alias - doclet = this.refs.__global__; - if ( doclet && doclet.meta.vars && hasOwnProp.call(doclet.meta.vars, basename) ) { - return [doclet.meta.vars[basename], basename]; - } - - id = 'astnode' + node.parent.hashCode(); - doclet = this.refs[id]; - if (!doclet) { - return ''; // global? - } - return doclet.longname || doclet.name; - } -}; - -/** - * Resolve what "this" refers to relative to a node. - * @param {astnode} node - The "this" node - * @returns {string} The longname of the enclosing node. - */ -exports.Parser.prototype.resolveThis = function(node) { - var memberof = {}; - var parent; - - if (node.type !== Token.COLON && node.enclosingFunction) { - // get documentation for the enclosing function - memberof.id = 'astnode' + node.enclosingFunction.hashCode(); - memberof.doclet = this.refs[memberof.id]; - - if (!memberof.doclet) { - return ''; // TODO handle global this? - } - - if (memberof.doclet['this']) { - return memberof.doclet['this']; - } - // like: Foo.constructor = function(n) { /** blah */ this.name = n; } - else if (memberof.doclet.kind === 'function' && memberof.doclet.memberof) { - return memberof.doclet.memberof; - } - // walk up to the closest class we can find - else if (memberof.doclet.kind === 'class' || memberof.doclet.kind === 'module') { - return memberof.doclet.longname || memberof.doclet.name; - } - else { - if (node.enclosingFunction){ - // memberof.doclet.meta.code.val - return this.resolveThis(node.enclosingFunction); - } - else { - return ''; // TODO handle global this? - } - } - } - else if (node.parent) { - if (node.parent.type === Token.COLON) { - parent = node.parent.parent; - } - else { - parent = node.parent; - } - - memberof.id = 'astnode' + parent.hashCode(); - memberof.doclet = this.refs[memberof.id]; - - if (!memberof.doclet) { - return ''; // global? - } - - return memberof.doclet.longname || memberof.doclet.name; - } - else { - return ''; // global? - } -}; - -/** - * Given 'var foo = { x: 1 }', find foo from x. - */ -exports.Parser.prototype.resolvePropertyParent = function(node) { - var memberof = {}; - var parent; - - if (node.parent && node.parent.type === Token.COLON) { - parent = node.parent.parent; - } - else { - parent = node.parent; - } - - if (parent) { - memberof.id = 'astnode' + parent.hashCode(); - memberof.doclet = this.refs[memberof.id]; - - if (memberof.doclet) { - return memberof; - } - } -}; - -/** - * Resolve what function a var is limited to. - * @param {astnode} node - * @param {string} basename The leftmost name in the long name: in foo.bar.zip the basename is foo. - */ -exports.Parser.prototype.resolveVar = function(node, basename) { - var doclet; - var enclosingFunction = node.enclosingFunction; - - if (!enclosingFunction) { - return ''; // global - } - - doclet = this.refs['astnode'+enclosingFunction.hashCode()]; - if (doclet && doclet.meta.vars && basename in doclet.meta.vars) { - return doclet.longname; - } - - return this.resolveVar(enclosingFunction, basename); -}; - -exports.Parser.prototype.addDocletRef = function(e) { - var node = e.code.node; - // allow lookup from value => doclet - if (e.doclet) { - this.refs['astnode' + node.hashCode()] = e.doclet; - } - // keep references to undocumented anonymous functions, too, as they might have scoped vars - else if ((node.type == Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) && - !this.refs['astnode' + node.hashCode()]) { - this.refs['astnode' + node.hashCode()] = { - longname: '', - meta: { - code: e.code - } - }; - } -}; - -exports.Parser.prototype.resolveEnum = function(e) { - var parent = this.resolvePropertyParent(e.code.node); - - if (parent && parent.doclet.isEnum) { - if (!parent.doclet.properties) { - parent.doclet.properties = []; - } - - // members of an enum inherit the enum's type - if (parent.doclet.type && !e.doclet.type) { - e.doclet.type = parent.doclet.type; - - } - - delete e.doclet.undocumented; - e.doclet.defaultvalue = e.doclet.meta.code.value; - - // add the doclet to the parent's properties - // use a copy of the doclet to avoid circular references - parent.doclet.properties.push( require('jsdoc/util/doop').doop(e.doclet) ); - } -}; - -/** - Fired whenever the parser encounters a JSDoc comment in the current source code. - @event jsdocCommentFound - @memberof module:jsdoc/src/parser.Parser - @param {event} e - @param {string} e.comment The text content of the JSDoc comment - @param {number} e.lineno The line number associated with the found comment. - @param {string} e.filename The file name associated with the found comment. -*/ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/lib/jsdoc/src/scanner.js b/rsc/scripts/jsdoc/lib/jsdoc/src/scanner.js deleted file mode 100644 index 914cf7fe..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/src/scanner.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - @module jsdoc/src/scanner - @requires module:fs - - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - - -var fs = require('jsdoc/fs'); -var path = require('jsdoc/path'); - -/** - @constructor - @mixes module:events - */ -exports.Scanner = function() {}; -exports.Scanner.prototype = Object.create( require('events').EventEmitter.prototype ); - -/** - Recursively searches the given searchPaths for js files. - @param {Array.} searchPaths - @param {number} [depth=1] - @fires sourceFileFound - */ -exports.Scanner.prototype.scan = function(searchPaths, depth, filter) { - var cwd = process.cwd(), - filePaths = [], - self = this; - - searchPaths = searchPaths || []; - depth = depth || 1; - - searchPaths.forEach(function($) { - var filepath = decodeURIComponent($); - if ( fs.statSync(filepath).isFile() ) { - filePaths.push( path.resolve(cwd, filepath) ); - } - else { - filePaths = filePaths.concat( fs.ls(filepath, depth).map(function(item) { - return path.resolve(cwd, item); - }) ); - } - }); - - filePaths = filePaths.filter(function($) { - return filter.isIncluded($); - }); - - filePaths = filePaths.filter(function($) { - var e = { fileName: $ }; - self.emit('sourceFileFound', e); - - return !e.defaultPrevented; - }); - - return filePaths; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tag.js b/rsc/scripts/jsdoc/lib/jsdoc/tag.js deleted file mode 100644 index ca59f95d..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tag.js +++ /dev/null @@ -1,103 +0,0 @@ -/*global env: true */ -/** - @overview - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - Functionality related to JSDoc tags. - @module jsdoc/tag - @requires jsdoc/tag/dictionary - @requires jsdoc/tag/validator - @requires jsdoc/tag/type - */ - -var jsdoc = { - tag: { - dictionary: require('jsdoc/tag/dictionary'), - validator: require('jsdoc/tag/validator'), - type: require('jsdoc/tag/type') - } -}; - -function trim(text, newlines) { - if (!text) { return ''; } - - if (newlines) { - return text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, ''); - } - else { - return text.replace(/^\s+|\s+$/g, ''); - } -} - -function processTagText(tag, tagDef) { - var tagType; - - if (tagDef.onTagText) { - tag.text = tagDef.onTagText(tag.text); - } - - if (tagDef.canHaveType || tagDef.canHaveName) { - /** The value property represents the result of parsing the tag text. */ - tag.value = {}; - - tagType = jsdoc.tag.type.parse(tag.text, tagDef.canHaveName, tagDef.canHaveType); - - // It is possible for a tag to *not* have a type but still have - // optional or defaultvalue, e.g. '@param [foo]'. - // Although tagType.type.length == 0 we should still copy the other properties. - if (tagType.type) { - if (tagType.type.length) { - tag.value.type = { - names: tagType.type - }; - } - tag.value.optional = tagType.optional; - tag.value.nullable = tagType.nullable; - tag.value.variable = tagType.variable; - tag.value.defaultvalue = tagType.defaultvalue; - } - - if (tagType.text && tagType.text.length) { - tag.value.description = tagType.text; - } - - if (tagDef.canHaveName) { - // note the dash is a special case: as a param name it means "no name" - if (tagType.name && tagType.name !== '-') { tag.value.name = tagType.name; } - } - } - else { - tag.value = tag.text; - } -} - -/** - Constructs a new tag object. Calls the tag validator. - @class - @classdesc Represents a single doclet tag. - @param {string} tagTitle - @param {string=} tagBody - @param {object=} meta - */ -var Tag = exports.Tag = function(tagTitle, tagBody, meta) { - meta = meta || {}; - - this.originalTitle = trim(tagTitle); - - /** The title part of the tag: @title text */ - this.title = jsdoc.tag.dictionary.normalise(this.originalTitle); - - var tagDef = jsdoc.tag.dictionary.lookUp(this.title); - - /** The text part of the tag: @title text */ - this.text = trim(tagBody, tagDef.keepsWhitespace); - - if (this.text) { - processTagText(this, tagDef); - } - - jsdoc.tag.validator.validate(this, tagDef, meta); -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tag/dictionary.js b/rsc/scripts/jsdoc/lib/jsdoc/tag/dictionary.js deleted file mode 100644 index e87cc88c..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tag/dictionary.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - @overview - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var hasOwnProp = Object.prototype.hasOwnProperty; - -var _tags = {}; -var _tagSynonyms = {}; -var _namespaces = []; -var dictionary; - - -/** @private */ -function TagDefinition(title, etc) { - var self = this; - etc = etc || {}; - - this.title = dictionary.normalise(title); - - Object.keys(etc).forEach(function(p) { - self[p] = etc[p]; - }); -} - -/** @private */ -TagDefinition.prototype.synonym = function(synonymName) { - _tagSynonyms[synonymName.toLowerCase()] = this.title; - return this; // chainable -}; - -/** @exports jsdoc/tag/dictionary */ -dictionary = { - /** @function */ - defineTag: function(title, opts) { - var def = new TagDefinition(title, opts); - // all the other dictionary functions use normalised names; we should too. - _tags[def.title] = def; - - if (opts.isNamespace) { - _namespaces.push(def.title); - } - - return _tags[def.title]; - }, - - /** @function */ - lookUp: function(title) { - title = dictionary.normalise(title); - - if ( hasOwnProp.call(_tags, title) ) { - return _tags[title]; - } - - return false; - }, - - /** @function */ - isNamespace: function(kind) { - if (kind) { - kind = dictionary.normalise(kind); - if ( _namespaces.indexOf(kind) !== -1) { - return true; - } - } - - return false; - }, - - /** @function */ - normalise: function(title) { - var canonicalName = title.toLowerCase(); - - if ( hasOwnProp.call(_tagSynonyms, canonicalName) ) { - return _tagSynonyms[canonicalName]; - } - - return canonicalName; - } -}; - -require('jsdoc/tag/dictionary/definitions').defineTags(dictionary); - -module.exports = dictionary; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tag/dictionary/definitions.js b/rsc/scripts/jsdoc/lib/jsdoc/tag/dictionary/definitions.js deleted file mode 100644 index 137b0286..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tag/dictionary/definitions.js +++ /dev/null @@ -1,677 +0,0 @@ -/*global app: true, env: true */ -/** - Define tags that are known in JSDoc. - @module jsdoc/tag/dictionary/definitions - - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var path = require('path'); - -/** @private */ -function setDocletKindToTitle(doclet, tag) { - doclet.addTag( 'kind', tag.title ); -} - -function setDocletScopeToTitle(doclet, tag) { - doclet.addTag( 'scope', tag.title ); -} - -function setDocletNameToValue(doclet, tag) { - if (tag.value && tag.value.description) { // as in a long tag - doclet.addTag( 'name', tag.value.description); - } - else if (tag.text) { // or a short tag - doclet.addTag('name', tag.text); - } -} - -function setDocletDescriptionToValue(doclet, tag) { - if (tag.value) { - doclet.addTag( 'description', tag.value ); - } -} - -function setNameToFile(doclet, tag) { - var name = ''; - if (doclet.meta.filename) { - // TODO: find the shortest path shared by all input files, and remove that from - // doclet.meta.path - name += path.basename(doclet.meta.path) + '/'; - doclet.addTag( 'name', name + doclet.meta.filename ); - } -} - -function setDocletMemberof(doclet, tag) { - if (tag.value && tag.value !== '') { - doclet.setMemberof(tag.value); - } -} - -function applyNamespace(docletOrNs, tag) { - if (typeof docletOrNs === 'string') { // ns - tag.value = app.jsdoc.name.applyNamespace(tag.value, docletOrNs); - } - else { // doclet - if (!docletOrNs.name) { - return; // error? - } - - //doclet.displayname = doclet.name; - docletOrNs.longname = app.jsdoc.name.applyNamespace(docletOrNs.name, tag.title); - } -} - -function setDocletNameToFilename(doclet, tag) { - // TODO: find the shortest path shared by all input files, and remove that from doclet.meta.path - var name = doclet.meta.path ? path.basename(doclet.meta.path) + '/' : ''; - name += doclet.meta.filename; - name = name.replace(/\.js$/i, ''); - - for (var i = 0, len = env.opts._.length; i < len; i++) { - if (name.indexOf(env.opts._[i]) === 0) { - name = name.replace(env.opts._[0], ''); - break; - } - } - doclet.name = name; -} - -function parseBorrows(doclet, tag) { - var m = /^(\S+)(?:\s+as\s+(\S+))?$/.exec(tag.text); - if (m) { - if (m[1] && m[2]) { - return { target: m[1], source: m[2] }; - } - else if (m[1]) { - return { target: m[1] }; - } - } else { - return {}; - } -} - -function firstWordOf(string) { - var m = /^(\S+)/.exec(string); - if (m) { return m[1]; } - else { return ''; } -} - -/** Populate the given dictionary with all known JSDoc tag definitions. - @param {module:jsdoc/tag/dictionary} dictionary -*/ -exports.defineTags = function(dictionary) { - - dictionary.defineTag('abstract', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - // since "abstract" is reserved word in JavaScript let's use "virtual" in code - doclet.virtual = true; - } - }) - .synonym('virtual'); - - dictionary.defineTag('access', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - // only valid values are private and protected, public is default - if ( /^(private|protected)$/i.test(tag.value) ) { - doclet.access = tag.value.toLowerCase(); - } - else { - delete doclet.access; - } - } - }); - - dictionary.defineTag('alias', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.alias = tag.value; - } - }); - - dictionary.defineTag('author', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.author) { doclet.author = []; } - doclet.author.push(tag.value); - } - }); - - // I add on to that - dictionary.defineTag('augments', { - mustHaveValue: true, - // Allow augments value to be specified as a normal type, e.g. {Type} - onTagText: function(text) { - var type = require('jsdoc/tag/type'), - tagType = type.parse(text, false, true); - return tagType.typeExpression || text; - }, - onTagged: function(doclet, tag) { - doclet.augment( firstWordOf(tag.value) ); - } - }) - .synonym('extends'); - - // that adds on to me - dictionary.defineTag('borrows', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - var borrows = parseBorrows(doclet, tag); - doclet.borrow(borrows.target, borrows.source); - } - }); - - // that adds all of it's members to me - dictionary.defineTag('mixes', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - var source = firstWordOf(tag.value); - doclet.mix(source); - } - }); - - dictionary.defineTag('class', { - onTagged: function(doclet, tag) { - doclet.addTag('kind', 'class'); - - // handle special case where both @class and @constructor tags exist in same doclet - if (tag.originalTitle === 'class') { - var looksLikeDesc = (tag.value || '').match(/\S+\s+\S+/); // multiple words after @class? - if ( looksLikeDesc || /@construct(s|or)\b/i.test(doclet.comment) ) { - doclet.classdesc = tag.value; // treat the @class tag as a @classdesc tag instead - return; - } - } - - setDocletNameToValue(doclet, tag); - } - }) - .synonym('constructor'); - - dictionary.defineTag('classdesc', { - onTagged: function(doclet, tag) { - doclet.classdesc = tag.value; - } - }); - - dictionary.defineTag('constant', { - canHaveType: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } - } - }) - .synonym('const'); - - dictionary.defineTag('copyright', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.copyright = tag.value; - } - }); - - dictionary.defineTag('constructs', { - onTagged: function(doclet, tag) { - var ownerClassName; - if (!tag.value) { - ownerClassName = '{@thisClass}'; // this can be resolved later in the handlers - } - else { - ownerClassName = firstWordOf(tag.value); - } - doclet.addTag('alias', ownerClassName); - doclet.addTag('kind', 'class'); - } - }); - - dictionary.defineTag('default', { - onTagged: function(doclet, tag) { - if (tag.value) { - doclet.defaultvalue = tag.value; - } - else if (doclet.meta && doclet.meta.code && typeof doclet.meta.code.value !== 'undefined') { - if (doclet.meta.code.type && /STRING|NUMBER|NAME|TRUE|FALSE/.test(doclet.meta.code.type)) { - doclet.defaultvalue = doclet.meta.code.value; - if (doclet.meta.code.type === 'STRING') { - // TODO: handle escaped quotes in values - doclet.defaultvalue = '"'+doclet.defaultvalue.replace(/"/g, '\\"')+'"'; - } - - if (doclet.defaultvalue === 'TRUE' || doclet.defaultvalue == 'FALSE') { - doclet.defaultvalue = doclet.defaultvalue.toLowerCase(); - } - } - else if (doclet.meta.code.type === 'NULL') { - // TODO: handle escaped quotes in values - doclet.defaultvalue = 'null'; - } - } - } - }) - .synonym('defaultvalue'); - - dictionary.defineTag('deprecated', { - // value is optional - onTagged: function(doclet, tag) { - doclet.deprecated = tag.value || true; - } - }); - - dictionary.defineTag('description', { - mustHaveValue: true - }) - .synonym('desc'); - - dictionary.defineTag('enum', { - canHaveType: true, - onTagged: function(doclet, tag) { - doclet.kind = 'member'; - doclet.isEnum = true; - if (tag.value && tag.value.type) { doclet.type = tag.value.type; } - } - }); - - dictionary.defineTag('event', { - isNamespace: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - } - }); - - dictionary.defineTag('example', { - keepsWhitespace: true, - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.examples) { doclet.examples = []; } - doclet.examples.push(tag.value); - } - }); - - dictionary.defineTag('exception', { - mustHaveValue: true, - canHaveType: true, - onTagged: function(doclet, tag) { - if (!doclet.exceptions) { doclet.exceptions = []; } - doclet.exceptions.push(tag.value); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } - } - }) - .synonym('throws'); - - dictionary.defineTag('external', { - canHaveType: true, - isNamespace: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } - } - }) - .synonym('host'); - - dictionary.defineTag('exports', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - var modName = firstWordOf(tag.value); - - doclet.addTag('alias', modName); - doclet.addTag('kind', 'module'); - } - }); - - dictionary.defineTag('file', { - onTagged: function(doclet, tag) { - setNameToFile(doclet, tag); - setDocletKindToTitle(doclet, tag); - setDocletDescriptionToValue(doclet, tag); - - doclet.preserveName = true; - } - }) - .synonym('fileoverview') - .synonym('overview'); - - dictionary.defineTag('fires', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.fires) { doclet.fires = []; } - applyNamespace('event', tag); - doclet.fires.push(tag.value); - } - }) - .synonym('emits'); - - dictionary.defineTag('function', { - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - } - }) - .synonym('func') - .synonym('method'); - - dictionary.defineTag('global', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - doclet.scope = 'global'; - delete doclet.memberof; - } - }); - - dictionary.defineTag('ignore', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - doclet.ignore = true; - } - }); - - dictionary.defineTag('inner', { - onTagged: function(doclet, tag) { - setDocletScopeToTitle(doclet, tag); - } - }); - - dictionary.defineTag('instance', { - onTagged: function(doclet, tag) { - setDocletScopeToTitle(doclet, tag); - } - }); - - dictionary.defineTag('kind', { - mustHaveValue: true - }); - - dictionary.defineTag('lends', { - onTagged: function(doclet, tag) { - doclet.alias = tag.value || ''; - doclet.addTag('undocumented'); - } - }); - - dictionary.defineTag('license', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.license = tag.value; - } - }); - - dictionary.defineTag('listens', { - mustHaveValue: true, - onTagged: function (doclet, tag) { - if (!doclet.listens) { doclet.listens = []; } - applyNamespace('event', tag); - doclet.listens.push(tag.value); - // TODO: verify that parameters match the event parameters? - } - }); - - dictionary.defineTag('member', { - canHaveType: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } - } - }) - .synonym('var'); - - dictionary.defineTag('memberof', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (tag.originalTitle === 'memberof!') { - doclet.forceMemberof = true; - if (tag.value === '') { - doclet.addTag('global'); - delete doclet.memberof; - } - } - setDocletMemberof(doclet, tag); - } - }) - .synonym('memberof!'); - - dictionary.defineTag('mixin', { - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - } - }); - - dictionary.defineTag('module', { - canHaveType: true, - isNamespace: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (!doclet.name) { - setDocletNameToFilename(doclet, tag); - } - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } - } - }); - - dictionary.defineTag('name', { - mustHaveValue: true - }); - - dictionary.defineTag('namespace', { - canHaveType: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - setDocletNameToValue(doclet, tag); - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - } - } - }); - - dictionary.defineTag('param', { - //mustHaveValue: true, // param name can be found in the source code if not provided - canHaveType: true, - canHaveName: true, - onTagged: function(doclet, tag) { - if (!doclet.params) { doclet.params = []; } - doclet.params.push(tag.value||{}); - } - }) - .synonym('argument') - .synonym('arg'); - - dictionary.defineTag('private', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - doclet.access = 'private'; - } - }); - - dictionary.defineTag('property', { - mustHaveValue: true, - canHaveType: true, - canHaveName: true, - onTagged: function(doclet, tag) { - if (!doclet.properties) { doclet.properties = []; } - doclet.properties.push(tag.value); - } - }) - .synonym('prop'); - - dictionary.defineTag('protected', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - doclet.access = 'protected'; - } - }); - - dictionary.defineTag('public', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - delete doclet.access; // public is default - } - }); - - // use this instead of old deprecated @final tag - dictionary.defineTag('readonly', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - doclet.readonly = true; - } - }); - - dictionary.defineTag('requires', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - var modName = firstWordOf(tag.value); - if (modName.indexOf('module:') !== 0) { - modName = 'module:'+modName; - } - if (!doclet.requires) { doclet.requires = []; } - doclet.requires.push(modName); - } - }); - - dictionary.defineTag('returns', { - mustHaveValue: true, - canHaveType: true, - onTagged: function(doclet, tag) { - if (!doclet.returns) { doclet.returns = []; } - doclet.returns.push(tag.value); - } - }) - .synonym('return'); - - dictionary.defineTag('see', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.see) { doclet.see = []; } - doclet.see.push(tag.value); - } - }); - - dictionary.defineTag('since', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.since = tag.value; - } - }); - - dictionary.defineTag('static', { - onTagged: function(doclet, tag) { - setDocletScopeToTitle(doclet, tag); - } - }); - - dictionary.defineTag('summary', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.summary = tag.value; - } - }); - - dictionary.defineTag('this', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.see) { doclet.see = []; } - doclet['this'] = firstWordOf(tag.value); - } - }); - - dictionary.defineTag('todo', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.todo) { doclet.todo = []; } - doclet.todo.push(tag.value); - } - }); - - dictionary.defineTag('tutorial', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - if (!doclet.tutorials) { doclet.tutorials = []; } - doclet.tutorials.push(tag.value); - } - }); - - dictionary.defineTag('type', { - mustHaveValue: true, - canHaveType: true, - onTagText: function(text) { - // any text must be formatted as a type, but for back compat braces are optional - if ( ! /^\{.+\}$/.test(text) ) { - text = '{ '+text+' }'; - } - return text; - }, - onTagged: function(doclet, tag) { - if (tag.value && tag.value.type) { - doclet.type = tag.value.type; - if (doclet.kind === 'function') { - doclet.addTag('returns', tag.text); // for backwards compatibility we allow @type for functions to imply return type - } - } - } - }); - - dictionary.defineTag('typedef', { - canHaveType: true, - canHaveName: true, - onTagged: function(doclet, tag) { - setDocletKindToTitle(doclet, tag); - - if (tag.value) { - if (tag.value.name) { - doclet.addTag('name', tag.value.name); - } - - // callbacks are always type {function} - if (tag.originalTitle === 'callback') { - doclet.type = { - names: [ - 'function' - ] - }; - } - else if (tag.value.type) { - doclet.type = tag.value.type; - } - } - } - }) - .synonym('callback'); - - dictionary.defineTag('undocumented', { - mustNotHaveValue: true, - onTagged: function(doclet, tag) { - doclet.undocumented = true; - doclet.comment = ''; - } - }); - - dictionary.defineTag('variation', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.variation = tag.value; - } - }); - - dictionary.defineTag('version', { - mustHaveValue: true, - onTagged: function(doclet, tag) { - doclet.version = tag.value; - } - }); -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tag/inline.js b/rsc/scripts/jsdoc/lib/jsdoc/tag/inline.js deleted file mode 100644 index b425ef87..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tag/inline.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @module jsdoc/tag/inline - * - * @author Jeff Williams - * @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - * Information about an inline tag that was found within a string. - * - * @typedef {Object} InlineTagInfo - * @memberof module:jsdoc/tag/inline - * @property {?string} completeTag - The entire inline tag, including its enclosing braces. - * @property {?string} tag - The tag whose text was found. - * @property {?string} text - The tag text that was found. - */ - -/** - * Information about the results of replacing inline tags within a string. - * - * @typedef {Object} InlineTagResult - * @memberof module:jsdoc/tag/inline - * @property {Array.} tags - The inline tags that were found. - * @property {string} newString - The updated text string after extracting or replacing the inline - * tags. - */ - -/** - * Text-replacing function for strings that contain an inline tag. - * - * @callback InlineTagReplacer - * @memberof module:jsdoc/tag/inline - * @param {string} string - The complete string containing the inline tag. - * @param {module:jsdoc/tag/inline.InlineTagInfo} tagInfo - Information about the inline tag. - * @return {string} An updated version of the complete string. - */ - -/** - * Replace all instances of multiple inline tags with other text. - * - * @param {string} string - The string in which to replace the inline tags. - * @param {Object} replacers - The functions that are used to replace text in the string. The keys - * must contain tag names (for example, `link`), and the values must contain functions with the - * type {@link module:jsdoc/tag/inline.InlineTagReplacer}. - * @return {module:jsdoc/tag/inline.InlineTagResult} The updated string, as well as information - * about the inline tags that were found. - */ -exports.replaceInlineTags = function(string, replacers) { - var tagInfo = []; - - function replaceMatch(replacer, tag, match, text) { - var matchedTag = { - completeTag: match, - tag: tag, - text: text - }; - tagInfo.push(matchedTag); - - return replacer.call(this, string, matchedTag); - } - - string = string || ''; - Object.keys(replacers).forEach(function(replacer) { - var tagRegExp = new RegExp('\\{@' + replacer + '\\s+(.+?)\\}', 'gi'); - var matches; - // call the replacer once for each match - while ( (matches = tagRegExp.exec(string)) !== null ) { - string = replaceMatch(replacers[replacer], replacer, matches[0], matches[1]); - } - }); - - return { - tags: tagInfo, - newString: string.trim() - }; -}; - -/** - * Replace all instances of an inline tag with other text. - * - * @param {string} string - The string in which to replace the inline tag. - * @param {string} tag - The name of the inline tag to replace. - * @param {module:jsdoc/tag/inline.InlineTagReplacer} replacer - The function that is used to - * replace text in the string. - * @return {module:jsdoc/tag/inline.InlineTagResult} The updated string, as well as information - * about the inline tags that were found. - */ -exports.replaceInlineTag = function(string, tag, replacer) { - var replacers = {}; - replacers[tag] = replacer; - - return exports.replaceInlineTags(string, replacers); -}; - -/** - * Extract inline tags from a string, replacing them with an empty string. - * - * @param {string} string - The string from which to extract text. - * @param {?string} tag - The inline tag to extract. - * @return {module:jsdoc/tag/inline.InlineTagResult} The updated string, as well as information - * about the inline tags that were found. - */ -exports.extractInlineTag = function(string, tag) { - return exports.replaceInlineTag(string, tag, function(str, tagInfo) { - return str.replace(tagInfo.completeTag, ''); - }); -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tag/type.js b/rsc/scripts/jsdoc/lib/jsdoc/tag/type.js deleted file mode 100644 index a14df5be..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tag/type.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * @module jsdoc/tag/type - * - * @author Michael Mathews - * @author Jeff Williams - * @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - * Information about a type expression extracted from tag text. - * - * @typedef TypeExpressionInfo - * @memberof module:jsdoc/tag/type - * @property {string} expression - The type expression. - * @property {string} text - The updated tag text. - */ - -/** @private */ -function unescapeBraces(text) { - return text.replace(/\\\{/g, '{') - .replace(/\\\}/g, '}'); -} - -/** - * Extract a type expression from the tag text. - * - * @private - * @param {string} string - The tag text. - * @return {module:jsdoc/tag/type.TypeExpressionInfo} The type expression and updated tag text. - */ - function extractTypeExpression(string) { - string = string || ''; - - var completeExpression; - var count = 0; - var position = 0; - var expression = ''; - var startIndex = string.indexOf('{'); - var textStartIndex; - - if (startIndex !== -1) { - // advance to the first character in the type expression - position = textStartIndex = startIndex + 1; - count++; - - while (position < string.length) { - switch (string[position]) { - case '\\': - // backslash is an escape character, so skip the next character - position++; - break; - case '{': - count++; - break; - case '}': - count--; - break; - default: - // do nothing - } - - if (count === 0) { - completeExpression = string.slice(startIndex, position + 1); - expression = string.slice(textStartIndex, position).trim(); - break; - } - - position++; - } - } - - string = completeExpression ? string.replace(completeExpression, '') : string; - - return { - expression: unescapeBraces(expression), - newString: string.trim() - }; -} - -/** @private */ -function getTagInfo(tagValue, canHaveName, canHaveType) { - var name = ''; - var typeExpression = ''; - var text = tagValue; - var expressionAndText; - var typeOverride; - - if (canHaveType) { - expressionAndText = extractTypeExpression(text); - typeExpression = expressionAndText.expression; - text = expressionAndText.newString; - } - - if (canHaveName) { - // like: name, [name], name text, [name] text, name - text, or [name] - text - text.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/); - name = RegExp.$1; - text = RegExp.$3; - } - - // an inline @type tag, like {@type Foo}, overrides the type expression - if (canHaveType) { - typeOverride = require('jsdoc/tag/inline').extractInlineTag(text, 'type'); - if (typeOverride.tags && typeOverride.tags[0]) { - typeExpression = typeOverride.tags[0].text || typeExpression; - } - text = typeOverride.newString; - } - - return { - name: name, - typeExpression: typeExpression, - text: text - }; -} - -/** - * Information provided in a JSDoc tag. - * - * @typedef {Object} TagInfo - * @memberof module:jsdoc/tag/type - * @property {string} TagInfo.defaultvalue - The default value of the member. - * @property {string} TagInfo.name - The name of the member (for example, `myParamName`). - * @property {boolean} TagInfo.nullable - Indicates whether the member can be set to `null` or - * `undefined`. - * @property {boolean} TagInfo.optional - Indicates whether the member is optional. - * @property {string} TagInfo.text - Descriptive text for the member (for example, `The user's email - * address.`). - * @property {Array.} TagInfo.type - The type or types that the member can contain (for - * example, `string` or `MyNamespace.MyClass`). - * @property {string} TagInfo.typeExpression - The type expression that was parsed to identify the - * types. - * @property {boolean} TagInfo.variable - Indicates whether the number of members that are provided - * can vary (for example, in a function that accepts any number of parameters). - */ - -/** - * Extract JSDoc-style type information from the name specified in the tag info, including the - * member name; whether the member is optional; and the default value of the member. - * - * @private - * @param {module:jsdoc/tag/type.TagInfo} tagInfo - Information contained in the tag. - * @return {module:jsdoc/tag/type.TagInfo} Updated information from the tag. - */ -function parseName(tagInfo) { - // like '[foo]' or '[ foo ]' or '[foo=bar]' or '[ foo=bar ]' or '[ foo = bar ]' - if ( /^\[\s*(.+?)\s*\]$/.test(tagInfo.name) ) { - tagInfo.name = RegExp.$1; - tagInfo.optional = true; - - // like 'foo=bar' or 'foo = bar' - if ( /^(.+?)\s*=\s*(.+)$/.test(tagInfo.name) ) { - tagInfo.name = RegExp.$1; - tagInfo.defaultvalue = RegExp.$2; - } - } - - return tagInfo; -} - -/** @private */ -function getTypeStrings(parsedType) { - var types = []; - - var catharsis = require('catharsis'); - var TYPES = catharsis.Types; - var util = require('util'); - - switch(parsedType.type) { - case TYPES.AllLiteral: - types.push('*'); - break; - case TYPES.FunctionType: - types.push('function'); - break; - case TYPES.NameExpression: - types.push(parsedType.name); - break; - case TYPES.NullLiteral: - types.push('null'); - break; - case TYPES.RecordType: - types.push('Object'); - break; - case TYPES.TypeApplication: - types.push( catharsis.stringify(parsedType) ); - break; - case TYPES.TypeUnion: - parsedType.elements.forEach(function(element) { - types = types.concat( getTypeStrings(element) ); - }); - break; - case TYPES.UndefinedLiteral: - types.push('undefined'); - break; - case TYPES.UnknownLiteral: - types.push('?'); - break; - default: - // this shouldn't happen - throw new Error( util.format('unrecognized type %s in parsed type: %j', parsedType.type, - parsedType) ); - } - - return types; -} - -/** - * Extract JSDoc-style and Closure Compiler-style type information from the type expression - * specified in the tag info. - * - * @private - * @param {module:jsdoc/tag/type.TagInfo} tagInfo - Information contained in the tag. - * @return {module:jsdoc/tag/type.TagInfo} Updated information from the tag. - */ -function parseTypeExpression(tagInfo) { - var catharsis = require('catharsis'); - var util = require('util'); - - var errorMessage; - var parsedType; - - // don't try to parse empty type expressions - if (!tagInfo.typeExpression) { - return tagInfo; - } - - try { - parsedType = catharsis.parse(tagInfo.typeExpression, {jsdoc: true}); - } - catch (e) { - // always re-throw so the caller has a chance to report which file was bad - throw new Error( util.format('unable to parse the type expression "%s": %s', - tagInfo.typeExpression, e.message) ); - } - - if (parsedType) { - tagInfo.type = tagInfo.type.concat( getTypeStrings(parsedType) ); - - // Catharsis and JSDoc use the same names for 'optional' and 'nullable'... - ['optional', 'nullable'].forEach(function(key) { - if (parsedType[key] !== null && parsedType[key] !== undefined) { - tagInfo[key] = parsedType[key]; - } - }); - - // ...but not 'variable'. - if (parsedType.repeatable !== null && parsedType.repeatable !== undefined) { - tagInfo.variable = parsedType.repeatable; - } - } - - return tagInfo; -} - -// TODO: allow users to add/remove type parsers (perhaps via plugins) -var typeParsers = [parseName, parseTypeExpression]; - -/** - * Parse the value of a JSDoc tag. - * - * @param {string} tagValue - The value of the tag. For example, the tag `@param {string} name` has - * a value of `{string} name`. - * @param {boolean} canHaveName - Indicates whether the value can include a symbol name. - * @param {boolean} canHaveType - Indicates whether the value can include a type expression that - * describes the symbol. - * @return {module:jsdoc/tag/type.TagInfo} Information obtained from the tag. - * @throws {Error} Thrown if a type expression cannot be parsed. - */ -exports.parse = function(tagValue, canHaveName, canHaveType) { - if (typeof tagValue !== 'string') { tagValue = ''; } - - var tagInfo = getTagInfo(tagValue, canHaveName, canHaveType); - tagInfo.type = tagInfo.type || []; - - typeParsers.forEach(function(parser) { - tagInfo = parser.call(this, tagInfo); - }); - - // if we wanted a type, but the parsers didn't add any type names, use the type expression - if (canHaveType && !tagInfo.type.length && tagInfo.typeExpression) { - tagInfo.type = [tagInfo.typeExpression]; - } - - return tagInfo; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tag/validator.js b/rsc/scripts/jsdoc/lib/jsdoc/tag/validator.js deleted file mode 100644 index 5621cced..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tag/validator.js +++ /dev/null @@ -1,62 +0,0 @@ -/*global env: true */ -/** - @module jsdoc/tag/validator - @requires jsdoc/tag/dictionary - - @author Michael Mathews - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - - -var dictionary = require('jsdoc/tag/dictionary'); -var format = require('util').format; - -function buildMessage(tagName, meta, desc) { - var result = format('The @%s tag %s. File: %s, line: %s', tagName, desc, meta.filename, - meta.lineno); - if (meta.comment) { - result += '\n' + meta.comment; - } - return result; -} - -function UnknownTagError(tagName, meta) { - this.name = 'UnknownTagError'; - this.message = buildMessage(tagName, meta, 'is not a known tag'); -} -UnknownTagError.prototype = new Error(); -UnknownTagError.prototype.constructor = UnknownTagError; - -function TagValueRequiredError(tagName, meta) { - this.name = 'TagValueRequiredError'; - this.message = buildMessage(tagName, meta, 'requires a value'); -} -TagValueRequiredError.prototype = new Error(); -TagValueRequiredError.prototype.constructor = TagValueRequiredError; - -function TagValueNotPermittedError(tagName, meta) { - this.name = 'TagValueNotPermittedError'; - this.message = buildMessage(tagName, meta, 'does not permit a value'); -} -TagValueNotPermittedError.prototype = new Error(); -TagValueNotPermittedError.prototype.constructor = TagValueNotPermittedError; - -/** - * Validate the given tag. - */ -exports.validate = function(tag, tagDef, meta) { - if (!tagDef && !env.conf.tags.allowUnknownTags) { - require('jsdoc/util/error').handle( new UnknownTagError(tag.title, meta) ); - } - - if (!tag.text) { - if (tagDef.mustHaveValue) { - require('jsdoc/util/error').handle( new TagValueRequiredError(tag.title, meta) ); - } - } - else { - if (tagDef.mustNotHaveValue) { - require('jsdoc/util/error').handle( new TagValueNotPermittedError(tag.title, meta) ); - } - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/template.js b/rsc/scripts/jsdoc/lib/jsdoc/template.js deleted file mode 100644 index 3fb2e762..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/template.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file Wrapper for underscore's template utility to allow loading templates from files. - * @author Rafał Wrzeszcz - * @author Matthew Christopher Kastor-Inare III - * @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var _ = require('underscore'), - fs = require('jsdoc/fs'), - path = require('path'); - - -/** - @module jsdoc/template - */ - -/** - @class - @classdesc Underscore template helper. - @param {string} path - Templates directory. - */ -exports.Template = function(path) { - this.path = path; - this.layout = null; - this.cache = {}; - // override default template tag settings - this.settings = { - evaluate : /<\?js([\s\S]+?)\?>/g, - interpolate: /<\?js=([\s\S]+?)\?>/g, - escape : /<\?js~([\s\S]+?)\?>/g - }; - -}; - -/** Loads template from given file. - @param {string} file - Template filename. - @return {function} Returns template closure. - */ -exports.Template.prototype.load = function(file) { - var _path = path.join(this.path, file); - return _.template(fs.readFileSync(_path, 'utf8'), null, this.settings); -}; - - -/** - Renders template using given data. - - This is low-level function, for rendering full templates use {@link Template.render()}. - - @param {string} file - Template filename. - @param {object} data - Template variables (doesn't have to be object, but passing variables dictionary is best way and most common use). - @return {string} Rendered template. - */ -exports.Template.prototype.partial = function(file, data) { - // load template into cache - if (!(file in this.cache)) { - this.cache[file] = this.load(file); - } - - // keep template helper context - return this.cache[file].call(this, data); -}; - -/** - Renders template with given data. - - This method automaticaly applies layout if set. - - @param {string} file - Template filename. - @param {object} data - Template variables (doesn't have to be object, but passing variables dictionary is best way and most common use). - @return {string} Rendered template. - */ -exports.Template.prototype.render = function(file, data) { - // main content - var content = this.partial(file, data); - - // apply layout - if (this.layout) { - data.content = content; - content = this.partial(this.layout, data); - } - - return content; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tutorial.js b/rsc/scripts/jsdoc/lib/jsdoc/tutorial.js deleted file mode 100644 index 81ef5b5b..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tutorial.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - @overview - @author Rafał Wrzeszcz - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var markdown = require('jsdoc/util/markdown'); - -/** Removes child tutorial from the parent. Does *not* unset child.parent though. - @param {Tutorial} parent - parent tutorial. - @param {Tutorial} child - Old child. - @private - */ -function removeChild(parent, child) { - var index = parent.children.indexOf(child); - if (index != -1) { - parent.children.splice(index, 1); - } -} - -/** Adds a child to the parent tutorial. Does *not* set child.parent though. - @param {Tutorial} parent - parent tutorial. - @param {Tutorial} child - New child. - @private - */ -function addChild(parent, child) { - parent.children.push(child); -} - -/** - @module jsdoc/tutorial - */ - -/** - @class - @classdesc Represents a single JSDoc tutorial. - @param {string} name - Tutorial name. - @param {string} content - Text content. - @param {number} type - Source formating. - */ -exports.Tutorial = function(name, content, type) { - this.title = this.name = name; - this.content = content; - this.type = type; - - // default values - this.parent = null; - this.children = []; -}; - -/** Moves children from current parent to different one. - @param {?Tutorial} parent - New parent. If null, the tutorial has no parent. - */ -exports.Tutorial.prototype.setParent = function(parent) { - // removes node from old parent - if (this.parent) { - removeChild(this.parent, this); - } - - this.parent = parent; - if (parent) { - addChild(parent, this); - } -}; - -/** Removes children from current node. - @param {Tutorial} child - Old child. - */ -exports.Tutorial.prototype.removeChild = function(child) { - child.setParent(null); -}; - -/** Adds new children to current node. - @param {Tutorial} child - New child. - */ -exports.Tutorial.prototype.addChild = function(child) { - child.setParent(this); -}; - -/** Prepares source. - @return {string} HTML source. - */ -exports.Tutorial.prototype.parse = function() { - switch (this.type) { - // nothing to do - case exports.TYPES.HTML: - return this.content; - - // markdown - case exports.TYPES.MARKDOWN: - var mdParse = markdown.getParser(); - return mdParse(this.content) - .replace(/&/g, '&') // because markdown escapes these - .replace(/</g, '<') - .replace(/>/g, '>'); - - // uhm... should we react somehow? - // if not then this case can be merged with TYPES.HTML - default: - return this.content; - } -}; - -/** Tutorial source types. - @enum {number} - */ -exports.TYPES = { - HTML: 1, - MARKDOWN: 2 -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/tutorial/resolver.js b/rsc/scripts/jsdoc/lib/jsdoc/tutorial/resolver.js deleted file mode 100644 index c07a3f7e..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/tutorial/resolver.js +++ /dev/null @@ -1,190 +0,0 @@ -/*global env: true */ -/** - @overview - @author Rafał Wrzeszcz - @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -/** - @module jsdoc/tutorial/resolver - */ - -var tutorial = require('jsdoc/tutorial'), - fs = require('jsdoc/fs'), - error = require('jsdoc/util/error'), - path = require('path'), - hasOwnProp = Object.prototype.hasOwnProperty, - conf = {}, - tutorials = {}, - finder = /^(.*)\.(x(?:ht)?ml|html?|md|markdown|json)$/i; - -/** checks if `conf` is the metadata for a single tutorial. - * A tutorial's metadata has a property 'title' and/or a property 'children'. - * @param {object} json - the object we want to test (typically from JSON.parse) - * @returns {boolean} whether `json` could be the metadata for a tutorial. - */ -function isTutorialJSON(json) { - // if conf.title exists or conf.children exists, it is metadata for a tutorial - return (hasOwnProp.call(json, 'title') || hasOwnProp.call(json, 'children')); -} - -/** Helper function that adds tutorial configuration to the `conf` variable. - * This helps when multiple tutorial configurations are specified in one object, - * or when a tutorial's children are specified as tutorial configurations as - * opposed to an array of tutorial names. - * - * Recurses as necessary to ensure all tutorials are added. - * - * @param {string} name - if `meta` is a configuration for a single tutorial, - * this is that tutorial's name. - * @param {object} meta - object that contains tutorial information. - * Can either be for a single tutorial, or for multiple - * (where each key in `meta` is the tutorial name and each - * value is the information for a single tutorial). - * Additionally, a tutorial's 'children' property may - * either be an array of strings (names of the child tutorials), - * OR an object giving the configuration for the child tutorials. - */ -function addTutorialConf(name, meta) { - var names, i; - if (isTutorialJSON(meta)) { - // if the children are themselves tutorial defintions as opposed to an - // array of strings, add each child. - if (hasOwnProp.call(meta, 'children') && !Array.isArray(meta.children)) { - names = Object.keys(meta.children); - for (i = 0; i < names.length; ++i) { - addTutorialConf(names[i], meta.children[names[i]]); - } - // replace with an array of names. - meta.children = names; - } - // check if the tutorial has already been defined... - if (hasOwnProp.call(conf, name)) { - error.handle(new Error("Tutorial " + name + "'s metadata is defined multiple times, only the first will be used.")); - } else { - conf[name] = meta; - } - } else { - // it's an object of tutorials, the keys are th etutorial names. - names = Object.keys(meta); - for (i = 0; i < names.length; ++i) { - addTutorialConf(names[i], meta[names[i]]); - } - } -} - -/** Adds new tutorial. - @param {tutorial.Tutorial} current - New tutorial. - */ -exports.addTutorial = function(current) { - if (hasOwnProp.call(tutorials, current.name)) { - error.handle(new Error("Tutorial with name " + current.name + " exists more than once, not adding (same name, different file extensions?)")); - } else { - tutorials[current.name] = current; - - // default temporary parent - current.setParent(exports.root); - } -}; - -/** Root tutorial. - @type tutorial.Tutorial - */ -exports.root = new tutorial.Tutorial('', ''); - -/** Additional instance method for root node. - @param {string} name - Tutorial name. - @return {tutorial.Tutorial} Tutorial instance. - */ -exports.root.getByName = function(name) { - return hasOwnProp.call(tutorials, name) && tutorials[name]; -}; - -/** Load tutorials from given path. - @param {string} _path - Tutorials directory. - */ -exports.load = function(_path) { - var match, - type, - name, - content, - current, - files = fs.ls(_path); - - // tutorials handling - files.forEach(function(file) { - match = file.match(finder); - - // any filetype that can apply to tutorials - if (match) { - name = path.basename(match[1]); - content = fs.readFileSync(file, env.opts.encoding); - - switch (match[2].toLowerCase()) { - // HTML type - case 'xml': - case 'xhtml': - case 'html': - case 'htm': - type = tutorial.TYPES.HTML; - break; - - // Markdown typs - case 'md': - case 'markdown': - type = tutorial.TYPES.MARKDOWN; - break; - - // configuration file - case 'json': - var meta = JSON.parse(content); - addTutorialConf(name, meta); - // don't add this as a tutorial - return; - - // how can it be? check `finder' regexp - default: - // not a file we want to work with - return; - } - - current = new tutorial.Tutorial(name, content, type); - exports.addTutorial(current); - } - }); -}; - -/** Resolves hierarchical structure. - */ -exports.resolve = function() { - var item, - current; - for (var name in conf) { - if ( hasOwnProp.call(conf, name) ) { - // TODO: should we complain about this? - if (!hasOwnProp.call(tutorials, name)) { - continue; - } - - item = conf[name]; - current = tutorials[name]; - - // set title - if (item.title) { - current.title = item.title; - } - - // add children - if (item.children) { - item.children.forEach(function(child) { - if (!hasOwnProp.call(tutorials, child)) { - error.handle( new Error("Missing child tutorial: " + child) ); - } - else { - tutorials[child].setParent(current); - } - }); - } - } - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/doop.js b/rsc/scripts/jsdoc/lib/jsdoc/util/doop.js deleted file mode 100644 index d3c148cb..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/doop.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - Deep clone a simple object. - @private - */ -var doop = exports.doop = function(o) { - var clone, - prop; - - if (o instanceof Object && o.constructor != Function) { - clone = o instanceof Array ? [] : {}; - - Object.keys(o).forEach(function(prop) { - clone[prop] = (o[prop] instanceof Object) ? doop(o[prop]) : o[prop]; - }); - - return clone; - } - - return o; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/dumper.js b/rsc/scripts/jsdoc/lib/jsdoc/util/dumper.js deleted file mode 100644 index e22279dc..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/dumper.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Recursively print out all names and values in a data structure. - * @module jsdoc/util/dumper - * @author Michael Mathews - * @license Apache License 2.0 - See file 'LICENSE.md' in this project. - */ - -var util = require('util'); - -var seenItems = []; -function seen(object) { - if (seenItems.indexOf(object) !== -1) { - return true; - } - - return false; -} - -// some objects are unwalkable, like Java native objects -function isUnwalkable(o) { - return (o && typeof o === 'object' && typeof o.constructor === 'undefined'); -} - -function isFunction(o) { - return (o && typeof o === 'function' || o instanceof Function); -} - -function isObject(o) { - return o && o instanceof Object || - (o && typeof o.constructor !== 'undefined' && o.constructor.name === 'Object'); -} - -function checkCircularRefs(o, func) { - if ( seen(o) ) { - return ''; - } - else { - seenItems.push(o); - return func.call(this, o); - } -} - -function walk(o) { - var result; - - if ( isUnwalkable(o) ) { - result = ''; - } - else if ( o === undefined ) { - result = 'undefined'; - } - else if ( Array.isArray(o) ) { - result = checkCircularRefs(o, function(arr) { - var newArray = []; - arr.forEach(function(item) { - newArray.push( walk(item) ); - }); - - return newArray; - }); - } - else if ( util.isRegExp(o) ) { - result = ''; - } - else if ( util.isDate(o) ) { - result = ''; - } - else if ( isFunction(o) ) { - result = ''; - } - else if ( isObject(o) && o !== null ) { - result = checkCircularRefs(o, function(obj) { - var newObj = {}; - Object.keys(obj).forEach(function(key) { - newObj[key] = walk(obj[key]); - }); - - return newObj; - }); - } - // should be safe to JSON.stringify() everything else - else { - result = o; - } - - return result; -} - -/** - * @param {*} object - */ -exports.dump = function(object) { - return JSON.stringify(walk(object), null, 4); -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/error.js b/rsc/scripts/jsdoc/lib/jsdoc/util/error.js deleted file mode 100644 index 57d950b3..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/error.js +++ /dev/null @@ -1,32 +0,0 @@ -/*global env: true */ -/** - Helper functions for handling errors. - @module jsdoc/util/error - */ - -/** - Handle an exception appropriately based on whether lenient mode is enabled: - - + If lenient mode is enabled, log the exception to the console. - + If lenient mode is not enabled, re-throw the exception. - @param {Error} e - The exception to handle. - @exception {Error} Re-throws the original exception unless lenient mode is enabled. - @memberof module:jsdoc/util/error - */ -exports.handle = function(e) { - var msg; - - if (env.opts.lenient) { - msg = e.message || JSON.stringify(e); - - // include the error type if it's an Error object - if (e instanceof Error) { - msg = e.name + ': ' + msg; - } - - console.log(msg); - } - else { - throw e; - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/global.js b/rsc/scripts/jsdoc/lib/jsdoc/util/global.js deleted file mode 100644 index dc20169d..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/global.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * The global object to which functions and properties can be assigned. - * @private - */ -module.exports = (function() { - return this; -}).call(null); diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/include.js b/rsc/scripts/jsdoc/lib/jsdoc/util/include.js deleted file mode 100644 index 54d1efa4..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/include.js +++ /dev/null @@ -1,19 +0,0 @@ -var path = require('path'); -var vm = require('jsdoc/util/vm'); - -/** - * Read and execute a JavaScript file in global scope. - * @private - * @param {string} filepath The path to the JavaScript file. May contain an absolute path or a - * path relative to env.dirname. - */ -module.exports = function(filepath) { - filepath = path.resolve(__dirname, filepath); - - try { - vm.getModule('jsdoc/util/include')(filepath); - } - catch (e) { - console.log('Cannot include ' + filepath + ': ' + e); - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/markdown.js b/rsc/scripts/jsdoc/lib/jsdoc/util/markdown.js deleted file mode 100644 index 3fdd217d..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/markdown.js +++ /dev/null @@ -1,112 +0,0 @@ -/*global env: true */ - -/** - * Provides access to Markdown-related functions. - * @module jsdoc/util/markdown - * @author Michael Mathews - * @author Ben Blank - */ - -/** - * Enumeration of Markdown parsers that are available. - * @enum {String} - */ -var parsers = { - /** The "[markdown-js](https://github.com/evilstreak/markdown-js)" (aka "evilstreak") parser. */ - evilstreak: "markdown", - /** - * The "GitHub-flavored Markdown" parser. - * @deprecated Replaced by "marked." - */ - gfm: "marked", - /** - * The "[Marked](https://github.com/chjj/marked)" parser. - */ - marked: "marked" -}; - -/** - * Escape underscores that occur within {@ ... } in order to protect them - * from the markdown parser(s). - * @param {String} source the source text to sanitize. - * @returns {String} `source` where underscores within {@ ... } have been - * protected with a preceding backslash (i.e. \_) -- the markdown parsers - * will strip the backslash and protect the underscore. - */ -function escapeUnderscores(source) { - return source.replace(/\{@[^}\r\n]+\}/g, function (wholeMatch) { - return wholeMatch.replace(/(^|[^\\])_/g, '$1\\_'); - }); -} - -/** - * Retrieve a function that accepts a single parameter containing Markdown source. The function uses - * the specified parser to transform the Markdown source to HTML, then returns the HTML as a string. - * - * @private - * @param {String} parser The name of the selected parser. - * @param {Object} [conf] Configuration for the selected parser, if any. - * @returns {Function} A function that accepts Markdown source, feeds it to the selected parser, and - * returns the resulting HTML. - * @throws {Error} If the name does not correspond to a known parser. - */ -function getParseFunction(parser, conf) { - conf = conf || {}; - var parse; - - if (parser === parsers.marked) { - parser = require(parser); - parser.setOptions({ - gfm: true, - tables: true, - breaks: false, - pedantic: false, - sanitize: true, - smartLists: true, - langPrefix: 'lang-' - }); - parse = function(source) { - source = escapeUnderscores(source); - return parser(source) - .replace(/\s+$/, '') - .replace(/'/g, "'"); - }; - parse._parser = parsers.marked; - return parse; - } else if (parser === parsers.evilstreak) { - parser = require(parser).markdown; - - parse = function(source) { - source = escapeUnderscores(source); - // evilstreak parser expects line endings to be \n - source = source.replace(/\r\n|\r/g, '\n'); - return parser.toHTML(source, conf.dialect); - }; - parse._parser = parsers.evilstreak; - return parse; - } else { - throw new Error("unknown Markdown parser: '" + parser + "'"); - } -} - -/** - * Retrieve a Markdown parsing function based on the value of the `conf.json` file's - * `env.conf.markdown` property. The parsing function accepts a single parameter containing Markdown - * source. The function uses the parser specified in `conf.json` to transform the Markdown source to - * HTML, then returns the HTML as a string. - * @returns {Function} A function that accepts Markdown source, feeds it to the selected parser, and - * returns the resulting HTML. - * @throws {Error} If the value of `env.conf.markdown.parser` does not correspond to a known parser. - */ -exports.getParser = function() { - var conf = env.conf.markdown; - if (conf && conf.parser) { - return getParseFunction(parsers[conf.parser], conf); - } else if (conf && conf.githubRepoOwner && conf.githubRepoName) { - // use GitHub-friendly parser if GitHub-specific options are present - return getParseFunction(parsers.gfm, conf); - } else { - // evilstreak is the default parser - return getParseFunction(parsers.evilstreak, conf); - } -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/templateHelper.js b/rsc/scripts/jsdoc/lib/jsdoc/util/templateHelper.js deleted file mode 100644 index 61b1ecc5..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/templateHelper.js +++ /dev/null @@ -1,711 +0,0 @@ -/*global env: true */ -/** - * @module jsdoc/util/templateHelper - */ - -var dictionary = require('jsdoc/tag/dictionary'); -var util = require('util'); - -var hasOwnProp = Object.prototype.hasOwnProperty; - -var files = {}; - -// each container gets its own html file -var containers = ['class', 'module', 'external', 'namespace', 'mixin']; - -var tutorials; - -/** Sets tutorials map. - @param {jsdoc.tutorial.Tutorial} root - Root tutorial node. - */ -exports.setTutorials = function(root) { - tutorials = root; -}; - -exports.globalName = 'global'; -exports.fileExtension = '.html'; -exports.scopeToPunc = { 'static': '.', 'inner': '~', 'instance': '#' }; - -function getNamespace(kind) { - if (dictionary.isNamespace(kind)) { - return kind + ':'; - } - return ''; -} - -function makeFilenameUnique(filename, str) { - var key = filename.toLowerCase(); - var nonUnique = true; - - // append enough underscores to make the filename unique - while (nonUnique) { - if ( files[key] && hasOwnProp.call(files, key) ) { - filename += '_'; - key = filename.toLowerCase(); - } else { - nonUnique = false; - } - } - - files[key] = str; - return filename; -} - -// compute it here just once -var nsprefix = /^(event|module|external):/; - -var htmlsafe = exports.htmlsafe = function(str) { - return str.replace(/` or `Array.<(MyClass|YourClass)>`. In these examples, the method attempts to - * replace `Array`, `MyClass`, and `YourClass` with links to the appropriate types. The link text - * is ignored for type applications. - * - * @param {string} longname - The longname (or URL) that is the target of the link. - * @param {string=} linkText - The text to display for the link, or `longname` if no text is - * provided. - * @param {Object} options - Options for building the link. - * @param {string=} options.cssClass - The CSS class (or classes) to include in the link's `` - * tag. - * @param {string=} options.fragmentId - The fragment identifier (for example, `name` in - * `foo.html#name`) to append to the link target. - * @param {string=} options.linkMap - The link map in which to look up the longname. - * @param {boolean=} options.monospace - Indicates whether to display the link text in a monospace - * font. - * @return {string} The HTML link, or the link text if the link is not available. - */ -function buildLink(longname, linkText, options) { - var catharsis = require('catharsis'); - - var classString = options.cssClass ? util.format(' class="%s"', options.cssClass) : ''; - var fragmentString = options.fragmentId ? '#' + options.fragmentId : ''; - var stripped; - var text; - var url; - var parsedType; - - // handle cases like: - // @see - // @see http://example.org - stripped = longname ? longname.replace(/^<|>$/g, '') : ''; - if ( hasUrlPrefix(stripped) ) { - url = stripped; - text = linkText || stripped; - } - // handle complex type expressions that may require multiple links - // (but skip anything that looks like an inline tag) - else if (longname && longname.search(/[<{(]/) !== -1 && /\{\@.+\}/.test(longname) === false) { - parsedType = parseType(longname); - return stringifyType(parsedType, options.cssClass, options.linkMap); - } - else { - url = hasOwnProp.call(options.linkMap, longname) ? options.linkMap[longname] : ''; - text = linkText || longname; - } - - text = options.monospace ? '' + text + '' : text; - - if (!url) { - return text; - } - else { - return util.format('%s', url, fragmentString, classString, text); - } -} - -/** - * Retrieve an HTML link to the symbol with the specified longname. If the longname is not - * associated with a URL, this method simply returns the link text, if provided, or the longname. - * - * The `longname` parameter can also contain a URL rather than a symbol's longname. - * - * This method supports type applications that can contain one or more types, such as - * `Array.` or `Array.<(MyClass|YourClass)>`. In these examples, the method attempts to - * replace `Array`, `MyClass`, and `YourClass` with links to the appropriate types. The link text - * is ignored for type applications. - * - * @param {string} longname - The longname (or URL) that is the target of the link. - * @param {string=} linkText - The text to display for the link, or `longname` if no text is - * provided. - * @param {string=} cssClass - The CSS class (or classes) to include in the link's `` tag. - * @param {string=} fragmentId - The fragment identifier (for example, `name` in `foo.html#name`) to - * append to the link target. - * @return {string} The HTML link, or a plain-text string if the link is not available. - */ -var linkto = exports.linkto = function(longname, linkText, cssClass, fragmentId) { - return buildLink(longname, linkText, { - cssClass: cssClass, - fragmentId: fragmentId, - linkMap: longnameToUrl - }); -}; - -function useMonospace(tag, text) { - var cleverLinks; - var monospaceLinks; - var result; - - if ( hasUrlPrefix(text) ) { - result = false; - } - else if (tag === 'linkplain') { - result = false; - } - else if (tag === 'linkcode') { - result = true; - } - else { - cleverLinks = env.conf.templates.cleverLinks; - monospaceLinks = env.conf.templates.monospaceLinks; - - if (monospaceLinks || cleverLinks) { - result = true; - } - } - - return result || false; -} - -function splitLinkText(text) { - var linkText; - var target; - var splitIndex; - - // if a pipe is not present, we split on the first space - splitIndex = text.indexOf('|'); - if (splitIndex === -1) { - splitIndex = text.indexOf(' '); - } - - if (splitIndex !== -1) { - linkText = text.substr(splitIndex + 1); - target = text.substr(0, splitIndex); - } - - return { - linkText: linkText, - target: target || text - }; -} - -var tutorialToUrl = exports.tutorialToUrl = function(tutorial) { - var node = tutorials.getByName(tutorial); - // no such tutorial - if (!node) { - require('jsdoc/util/error').handle( new Error('No such tutorial: '+tutorial) ); - return; - } - - var url; - // define the URL if necessary - if (!hasOwnProp.call(tutorialLinkMap.nameToUrl, node.name)) { - url = 'tutorial-' + getUniqueFilename(node.name); - tutorialLinkMap.nameToUrl[node.name] = url; - tutorialLinkMap.urlToName[url] = node.name; - } - - return tutorialLinkMap.nameToUrl[node.name]; -}; - -/** - * Retrieve a link to a tutorial, or the name of the tutorial if the tutorial is missing. If the - * `missingOpts` parameter is supplied, the names of missing tutorials will be prefixed by the - * specified text and wrapped in the specified HTML tag and CSS class. - * - * @todo Deprecate missingOpts once we have a better error-reporting mechanism. - * @param {string} tutorial The name of the tutorial. - * @param {string} content The link text to use. - * @param {object} [missingOpts] Options for displaying the name of a missing tutorial. - * @param {string} missingOpts.classname The CSS class to wrap around the tutorial name. - * @param {string} missingOpts.prefix The prefix to add to the tutorial name. - * @param {string} missingOpts.tag The tag to wrap around the tutorial name. - * @return {string} An HTML link to the tutorial, or the name of the tutorial with the specified - * options. - */ -var toTutorial = exports.toTutorial = function(tutorial, content, missingOpts) { - if (!tutorial) { - require('jsdoc/util/error').handle( new Error('Missing required parameter: tutorial') ); - return; - } - - var node = tutorials.getByName(tutorial); - // no such tutorial - if (!node) { - missingOpts = missingOpts || {}; - var tag = missingOpts.tag; - var classname = missingOpts.classname; - - var link = tutorial; - if (missingOpts.prefix) { - link = missingOpts.prefix + link; - } - if (tag) { - link = '<' + tag + (classname ? (' class="' + classname + '">') : '>') + link; - link += ''; - } - return link; - } - - content = content || node.title; - - return '' + content + ''; -}; - -/** Find symbol {@link ...} and {@tutorial ...} strings in text and turn into html links */ -exports.resolveLinks = function(str) { - var replaceInlineTags = require('jsdoc/tag/inline').replaceInlineTags; - - function extractLeadingText(string, completeTag) { - var tagIndex = string.indexOf(completeTag); - var leadingText = null; - var leadingTextInfo = /\[(.+?)\]/.exec(string); - - // did we find leading text, and if so, does it immediately precede the tag? - if ( leadingTextInfo && leadingTextInfo.index && - (leadingTextInfo.index + leadingTextInfo[0].length === tagIndex) ) { - string = string.replace(leadingTextInfo[0], ''); - leadingText = leadingTextInfo[1]; - } - - return { - leadingText: leadingText, - string: string - }; - } - - function processLink(string, tagInfo) { - var leading = extractLeadingText(string, tagInfo.completeTag); - var linkText = leading.leadingText; - var monospace; - var split; - var target; - string = leading.string; - - split = splitLinkText(tagInfo.text); - target = split.target; - linkText = linkText || split.linkText; - - monospace = useMonospace(tagInfo.tag, tagInfo.text); - - return string.replace( tagInfo.completeTag, buildLink(target, linkText, { - linkMap: longnameToUrl, - monospace: monospace - }) ); - } - - function processTutorial(string, tagInfo) { - var leading = extractLeadingText(string, tagInfo.completeTag); - string = leading.string; - - return string.replace( tagInfo.completeTag, toTutorial(tagInfo.text, leading.leadingText) ); - } - - var replacers = { - link: processLink, - linkcode: processLink, - linkplain: processLink, - tutorial: processTutorial - }; - - return replaceInlineTags(str, replacers).newString; -}; - -/** Convert tag text like "Jane Doe " into a mailto link */ -exports.resolveAuthorLinks = function(str) { - var author; - var matches = str.match(/^\s?([\s\S]+)\b\s+<(\S+@\S+)>\s?$/); - if (matches && matches.length === 3) { - author = '' + htmlsafe(matches[1]) + ''; - } - else { - author = htmlsafe(str); - } - - return author; -}; - -/** - * Find items in a TaffyDB database that match the specified key-value pairs. - * @param {TAFFY} data The TaffyDB database to search. - * @param {object|function} spec Key-value pairs to match against (for example, - * `{ longname: 'foo' }`), or a function that returns `true` if a value matches or `false` if it - * does not match. - * @return {array} The matching items. - */ -var find = exports.find = function(data, spec) { - return data(spec).get(); -}; - -/** - * Check whether a symbol is a function and is the only symbol exported by a module (as in - * `module.exports = function() {};`). - * - * @private - * @param {module:jsdoc/doclet.Doclet} doclet - The doclet for the symbol. - * @return {boolean} `true` if the symbol is a function and is the only symbol exported by a module; - * otherwise, `false`. - */ -function isModuleFunction(doclet) { - return doclet.longname && doclet.longname === doclet.name && - doclet.longname.indexOf('module:') === 0 && doclet.kind === 'function'; -} - -/** - * Retrieve all of the following types of members from a set of doclets: - * - * + Classes - * + Externals - * + Globals - * + Mixins - * + Modules - * + Namespaces - * + Events - * @param {TAFFY} data The TaffyDB database to search. - * @return {object} An object with `classes`, `externals`, `globals`, `mixins`, `modules`, - * `events`, and `namespaces` properties. Each property contains an array of objects. - */ -exports.getMembers = function(data) { - var members = { - classes: find( data, {kind: 'class'} ), - externals: find( data, {kind: 'external'} ), - events: find( data, {kind: 'event'} ), - globals: find(data, { - kind: ['member', 'function', 'constant', 'typedef'], - memberof: { isUndefined: true } - }), - mixins: find( data, {kind: 'mixin'} ), - modules: find( data, {kind: 'module'} ), - namespaces: find( data, {kind: 'namespace'} ) - }; - - // functions that are also modules (as in "module.exports = function() {};") are not globals - members.globals = members.globals.filter(function(doclet) { - if ( isModuleFunction(doclet) ) { - return false; - } - - return true; - }); - - return members; -}; - -/** - * Retrieve the member attributes for a doclet (for example, `virtual`, `static`, and - * `readonly`). - * @param {object} d The doclet whose attributes will be retrieved. - * @return {array} The member attributes for the doclet. - */ -exports.getAttribs = function(d) { - var attribs = []; - - if (d.virtual) { - attribs.push('virtual'); - } - - if (d.access && d.access !== 'public') { - attribs.push(d.access); - } - - if (d.scope && d.scope !== 'instance' && d.scope !== 'global') { - if (d.kind == 'function' || d.kind == 'member' || d.kind == 'constant') { - attribs.push(d.scope); - } - } - - if (d.readonly === true) { - if (d.kind == 'member') { - attribs.push('readonly'); - } - } - - if (d.kind === 'constant') { - attribs.push('constant'); - } - - return attribs; -}; - -/** - * Retrieve links to allowed types for the member. - * - * @param {Object} d - The doclet whose types will be retrieved. - * @param {string} [cssClass] - The CSS class to include in the `class` attribute for each link. - * @return {Array.} HTML links to allowed types for the member. - */ -exports.getSignatureTypes = function(d, cssClass) { - var types = []; - - if (d.type && d.type.names) { - types = d.type.names; - } - - if (types && types.length) { - types = types.map(function(t) { - return linkto(t, htmlsafe(t), cssClass); - }); - } - - return types; -}; - -/** - * Retrieve names of the parameters that the member accepts. If a value is provided for `optClass`, - * the names of optional parameters will be wrapped in a `` tag with that class. - * @param {object} d The doclet whose parameter names will be retrieved. - * @param {string} [optClass] The class to assign to the `` tag that is wrapped around the - * names of optional parameters. If a value is not provided, optional parameter names will not be - * wrapped with a `` tag. Must be a legal value for a CSS class name. - * @return {array} An array of parameter names, with or without `` tags wrapping the - * names of optional parameters. - */ -exports.getSignatureParams = function(d, optClass) { - var pnames = []; - - if (d.params) { - d.params.forEach(function(p) { - if (p.name && p.name.indexOf('.') === -1) { - if (p.optional && optClass) { - pnames.push('' + p.name + ''); - } - else { - pnames.push(p.name); - } - } - }); - } - - return pnames; -}; - -/** - * Retrieve links to types that the member can return. - * - * @param {Object} d - The doclet whose types will be retrieved. - * @param {string} [cssClass] - The CSS class to include in the `class` attribute for each link. - * @return {Array.} HTML links to types that the member can return. - */ -exports.getSignatureReturns = function(d, cssClass) { - var returnTypes = []; - - if (d.returns) { - d.returns.forEach(function(r) { - if (r.type && r.type.names) { - if (!returnTypes.length) { - returnTypes = r.type.names; - } - } - }); - } - - if (returnTypes && returnTypes.length) { - returnTypes = returnTypes.map(function(r) { - return linkto(r, htmlsafe(r), cssClass); - }); - } - - return returnTypes; -}; - -/** - * Retrieve links to a member's ancestors. - * - * @param {TAFFY} data - The TaffyDB database to search. - * @param {Object} doclet - The doclet whose ancestors will be retrieved. - * @param {string} [cssClass] - The CSS class to include in the `class` attribute for each link. - * @return {Array.} HTML links to a member's ancestors. - */ -exports.getAncestorLinks = function(data, doclet, cssClass) { - var ancestors = [], - doc = doclet.memberof; - - while (doc) { - doc = find( data, {longname: doc}, false ); - if (doc) { doc = doc[0]; } - if (!doc) { break; } - ancestors.unshift( linkto(doc.longname, (exports.scopeToPunc[doc.scope] || '') + doc.name, - cssClass) ); - doc = doc.memberof; - } - if (ancestors.length) { - ancestors[ancestors.length - 1] += (exports.scopeToPunc[doclet.scope] || ''); - } - return ancestors; -}; - -/** - * Iterates through all the doclets in `data`, ensuring that if a method - * @listens to an event, then that event has a 'listeners' array with the - * longname of the listener in it. - * - * @param {TAFFY} data - The TaffyDB database to search. - */ -exports.addEventListeners = function(data) { - // TODO: do this on the *pruned* data - // find all doclets that @listen to something. - var listeners = find(data, function () { return this.listens && this.listens.length; }); - - if (!listeners.length) { - return; - } - - var doc, - l, - _events = {}; // just a cache to prevent me doing so many lookups - - listeners.forEach(function (listener) { - l = listener.listens; - l.forEach(function (eventLongname) { - doc = _events[eventLongname] || find(data, {longname: eventLongname, kind: 'event'})[0]; - if (doc) { - if (!doc.listeners) { - doc.listeners = [listener.longname]; - } else { - doc.listeners.push(listener.longname); - } - _events[eventLongname] = _events[eventLongname] || doc; - } - }); - }); -}; - -/** - * Remove members that will not be included in the output, including: - * - * + Undocumented members. - * + Members tagged `@ignore`. - * + Members of anonymous classes. - * + Members tagged `@private`, unless the `private` option is enabled. - * @param {TAFFY} data The TaffyDB database to prune. - * @return {TAFFY} The pruned database. - */ -exports.prune = function(data) { - data({undocumented: true}).remove(); - data({ignore: true}).remove(); - if (!env.opts.private) { data({access: 'private'}).remove(); } - data({memberof: ''}).remove(); - - return data; -}; - -var registerLink = exports.registerLink = function(longname, url) { - linkMap.longnameToUrl[longname] = url; - linkMap.urlToLongname[url] = longname; -}; - -/** - * Get a longname's filename if one has been registered; otherwise, generate a unique filename, then - * register the filename. - * @private - */ -function getFilename(longname) { - var url; - - if ( longnameToUrl[longname] && hasOwnProp.call(longnameToUrl, longname) ) { - url = longnameToUrl[longname]; - } else { - url = getUniqueFilename(longname); - registerLink(longname, url); - } - - return url; -} - -/** Turn a doclet into a URL. */ -exports.createLink = function(doclet) { - var url = ''; - var longname = doclet.longname; - var filename; - - if ( containers.indexOf(doclet.kind) !== -1 || isModuleFunction(doclet) ) { - url = getFilename(longname); - } - else { - filename = getFilename(doclet.memberof || exports.globalName); - url = filename + '#' + getNamespace(doclet.kind) + doclet.name; - } - - return url; -}; diff --git a/rsc/scripts/jsdoc/lib/jsdoc/util/vm.js b/rsc/scripts/jsdoc/lib/jsdoc/util/vm.js deleted file mode 100644 index eb7048b1..00000000 --- a/rsc/scripts/jsdoc/lib/jsdoc/util/vm.js +++ /dev/null @@ -1,83 +0,0 @@ -/*global Packages: true */ -/** - * Helper functions to enable JSDoc to run on multiple JavaScript virtual machines. - * @module jsdoc/util/vm - */ - - var os = require('os'); - -// These strings represent directory names; do not modify them! -/** @private */ -const RHINO = exports.RHINO = 'rhino'; -/** @private */ -const NODEJS = exports.NODEJS = 'nodejs'; - -// hacky conversion from Windows path to URI -function pathToUri(filepath) { - var uri = filepath; - - // get drive - var drive = uri.match(/^[A-Za-z]/)[0] || ''; - // strip drive/colon (if present; UNC paths won't have either) - uri = uri.replace(/^:?([A-Za-z]\:)?/, ''); - // replace spaces with %20 - uri = uri.replace(/\s/g, '%20'); - // prepend drive (if present) - if (drive) { - uri = drive + ':' + uri; - } - // prepend URI scheme - uri = 'file:/' + uri; - - return uri; -} - -/** - * The JavaScript VM that is executing JSDoc: - * - * + `module:jsdoc/util/vm.RHINO`: Mozilla Rhino. - * + `module:jsdoc/util/vm.NODEJS`: Node.js (not currently supported). - */ -var vm = exports.vm = (function() { - if (Packages && typeof Packages === 'object' && - Object.prototype.toString.call(Packages) === '[object JavaPackage]') { - return RHINO; - } else if ( require && require.main && module && (require.main === module) ) { - return NODEJS; - } else { - // unknown VM - throw new Error('Unable to identify the current JavaScript VM.'); - } -})(); - -/** - * Load the VM-specific implementation of a module. - * - * @param {string} modulePath - The relative path to the module. Use the same format as when calling - * `require()`. - * @return {object} An object containing VM-specific functions for the requested module. - */ -exports.getModule = function(modulePath) { - modulePath = [__dirname, vm, modulePath].join('/').replace(/ /g, '%20'); - if (os.platform() === 'win32') { - modulePath = pathToUri(modulePath); - } - - return require(modulePath); -}; - -/** - * Check whether Mozilla Rhino is running JSDoc. - * @return {boolean} Set to `true` if the current VM is Mozilla Rhino. - */ -exports.isRhino = function() { - return vm === RHINO; -}; - -/** - * Check whether Node.js is running JSDoc. (Node.js is not currently supported.) - * @return {boolean} Set to `true` if the current VM is Node.js. - */ -exports.isNodejs = function() { - return vm === NODEJS; -}; diff --git a/rsc/scripts/jsdoc/node_modules/async/LICENSE b/rsc/scripts/jsdoc/node_modules/async/LICENSE deleted file mode 100644 index b7f9d500..00000000 --- a/rsc/scripts/jsdoc/node_modules/async/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Caolan McMahon - -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. diff --git a/rsc/scripts/jsdoc/node_modules/async/index.js b/rsc/scripts/jsdoc/node_modules/async/index.js deleted file mode 100644 index 8e238453..00000000 --- a/rsc/scripts/jsdoc/node_modules/async/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// This file is just added for convenience so this repository can be -// directly checked out into a project's deps folder -module.exports = require('./lib/async'); diff --git a/rsc/scripts/jsdoc/node_modules/async/lib/async.js b/rsc/scripts/jsdoc/node_modules/async/lib/async.js deleted file mode 100644 index 7cc4f5ea..00000000 --- a/rsc/scripts/jsdoc/node_modules/async/lib/async.js +++ /dev/null @@ -1,692 +0,0 @@ -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - } - else { - async.nextTick = process.nextTick; - } - - async.forEach = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(null); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(null); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - async.forEachLimit = function (arr, limit, iterator, callback) { - callback = callback || function () {}; - if (!arr.length || limit <= 0) { - return callback(); - } - var completed = 0; - var started = 0; - var running = 0; - - (function replenish () { - if (completed === arr.length) { - return callback(); - } - - while (running < limit && started < arr.length) { - started += 1; - running += 1; - iterator(arr[started - 1], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - running -= 1; - if (completed === arr.length) { - callback(); - } - else { - replenish(); - } - } - }); - } - })(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - main_callback = function () {}; - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var results = {}; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners.slice(0), function (fn) { - fn(); - }); - }; - - addListener(function () { - if (_keys(results).length === keys.length) { - callback(null, results); - callback = function () {}; - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && results.hasOwnProperty(x)); - }, true) && !results.hasOwnProperty(k); - }; - if (ready()) { - task[task.length - 1](taskCallback, results); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback, results); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - callback = callback || function () {}; - if (!tasks.length) { - return callback(); - } - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var q = { - tasks: [], - concurrency: concurrency, - saturated: null, - empty: null, - drain: null, - push: function (data, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _forEach(data, function(task) { - q.tasks.push({ - data: task, - callback: typeof callback === 'function' ? callback : null - }); - if (q.saturated && q.tasks.length == concurrency) { - q.saturated(); - } - async.nextTick(q.process); - }); - }, - process: function () { - if (workers < q.concurrency && q.tasks.length) { - var task = q.tasks.shift(); - if(q.empty && q.tasks.length == 0) q.empty(); - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - if(q.drain && q.tasks.length + workers == 0) q.drain(); - q.process(); - }); - } - }, - length: function () { - return q.tasks.length; - }, - running: function () { - return workers; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - var queues = {}; - hasher = hasher || function (x) { - return x; - }; - var memoized = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else if (key in queues) { - queues[key].push(callback); - } - else { - queues[key] = [callback]; - fn.apply(null, args.concat([function () { - memo[key] = arguments; - var q = queues[key]; - delete queues[key]; - for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); - } - }])); - } - }; - memoized.unmemoized = fn; - return memoized; - }; - - async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; - }; - -}()); diff --git a/rsc/scripts/jsdoc/node_modules/async/package.json b/rsc/scripts/jsdoc/node_modules/async/package.json deleted file mode 100644 index 1e3814d8..00000000 --- a/rsc/scripts/jsdoc/node_modules/async/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "async", - "description": "Higher-order functions and common patterns for asynchronous code", - "main": "./index", - "author": { - "name": "Caolan McMahon" - }, - "version": "0.1.22", - "repository": { - "type": "git", - "url": "http://github.com/caolan/async.git" - }, - "bugs": { - "url": "http://github.com/caolan/async/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/caolan/async/raw/master/LICENSE" - } - ], - "devDependencies": { - "nodeunit": ">0.0.0", - "uglify-js": "1.2.x", - "nodelint": ">0.0.0" - }, - "readme": "# Async.js\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [node.js](http://nodejs.org), it can also be used directly in the\nbrowser.\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (map, reduce, filter, forEach…) as well as some common patterns\nfor asynchronous control flow (parallel, series, waterfall…). All these\nfunctions assume you follow the node.js convention of providing a single\ncallback as the last argument of your async function.\n\n\n## Quick Examples\n\n async.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n });\n\n async.filter(['file1','file2','file3'], path.exists, function(results){\n // results now equals an array of the existing files\n });\n\n async.parallel([\n function(){ ... },\n function(){ ... }\n ], callback);\n\n async.series([\n function(){ ... },\n function(){ ... }\n ]);\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n\n## Download\n\nReleases are available for download from\n[GitHub](http://github.com/caolan/async/downloads).\nAlternatively, you can install using Node Package Manager (npm):\n\n npm install async\n\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed\n\n__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped\n\n\n## In the Browser\n\nSo far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:\n\n \n \n\n\n## Documentation\n\n### Collections\n\n* [forEach](#forEach)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [until](#until)\n* [waterfall](#waterfall)\n* [queue](#queue)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n\n### forEach(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the forEach function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n // assuming openFiles is an array of file names and saveFile is a function\n // to save the modified contents of that file:\n\n async.forEach(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n });\n\n---------------------------------------\n\n\n### forEachSeries(arr, iterator, callback)\n\nThe same as forEach only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n\n### forEachLimit(arr, limit, iterator, callback)\n\nThe same as forEach only the iterator is applied to batches of items in the\narray, in series. The next batch of iterators is only called once the current\none has completed processing.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - How many items should be in each batch.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n // Assume documents is an array of JSON objects and requestApi is a\n // function that interacts with a rate-limited REST api.\n\n async.forEachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n });\n---------------------------------------\n\n\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n async.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n });\n\n---------------------------------------\n\n\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(results) - A callback which is called after all the iterator\n functions have finished.\n\n__Example__\n\n async.filter(['file1','file2','file3'], path.exists, function(results){\n // results now equals an array of the existing files\n });\n\n---------------------------------------\n\n\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n\n### rejectSeries(arr, iterator, callback)\n\nThe same as filter, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then its probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n array to produce the next step in the reduction. The iterator is passed a\n callback which accepts an optional error as its first argument, and the state\n of the reduction as the second. If an error is passed to the callback, the\n reduction is stopped and the main callback is immediately called with the\n error.\n* callback(err, result) - A callback which is called after all the iterator\n functions have finished. Result is the reduced value.\n\n__Example__\n\n async.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n }, function(err, result){\n // result is now equal to the last value of memo, which is 6\n });\n\n---------------------------------------\n\n\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value undefined if none passed.\n\n__Example__\n\n async.detect(['file1','file2','file3'], path.exists, function(result){\n // result now equals the first file in the list that exists\n });\n\n---------------------------------------\n\n\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and a value to use as the sort criteria.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is the items from\n the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n async.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n }, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n });\n\n\n---------------------------------------\n\n\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n either true or false depending on the values of the async tests.\n\n__Example__\n\n async.some(['file1','file2','file3'], path.exists, function(result){\n // if result is true then at least one of the files exists\n });\n\n---------------------------------------\n\n\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called after all the iterator\n functions have finished. Result will be either true or false depending on\n the values of the async tests.\n\n__Example__\n\n async.every(['file1','file2','file3'], path.exists, function(result){\n // if result is true then every file exists\n });\n\n---------------------------------------\n\n\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array containing\n the concatenated results of the iterator function.\n\n__Example__\n\n async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n });\n\n---------------------------------------\n\n\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n a callback it must call on completion.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets an array of all the arguments passed to\n the callbacks used in the array.\n\n__Example__\n\n async.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n },\n ],\n // optional callback\n function(err, results){\n // results is now equal to ['one', 'two']\n });\n\n\n // an example using an object instead of an array\n async.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n },\n },\n function(err, results) {\n // results is now equal to: {one: 1, two: 2}\n });\n\n\n---------------------------------------\n\n\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed a\n callback it must call on completion.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets an array of all the arguments passed to\n the callbacks used in the array.\n\n__Example__\n\n async.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n },\n ],\n // optional callback\n function(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n });\n\n\n // an example using an object instead of an array\n async.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n },\n },\n function(err, results) {\n // results is now equals to: {one: 1, two: 2}\n });\n\n\n---------------------------------------\n\n\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n passed a callback which must be called once it has completed with an optional\n error as the first argument.\n* callback(err) - A callback which is called after the test fails and repeated\n execution of fn has stopped.\n\n__Example__\n\n var count = 0;\n\n async.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n );\n\n\n---------------------------------------\n\n\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n\n---------------------------------------\n\n\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a callback it\n must call on completion.\n* callback(err, [results]) - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n async.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n ], function (err, result) {\n // result now equals 'done' \n });\n\n\n---------------------------------------\n\n\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n task.\n* concurrency - An integer for determining how many worker functions should be\n run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n run in parallel. This property can be changed after a queue is created to\n alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n // create a queue object with concurrency 2\n\n var q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n }, 2);\n\n\n // assign a callback\n q.drain = function() {\n console.log('all items have been processed');\n }\n\n // add some items to the queue\n\n q.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n });\n q.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n });\n\n // add some items to the queue (batch-wise)\n\n q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n });\n\n\n---------------------------------------\n\n\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n requirements, with the function itself the last item in the array. The key\n used for each function or array is used when specifying requirements. The\n syntax is easier to understand by looking at the example.\n* callback(err, results) - An optional callback which is called when all the\n tasks have been completed. The callback will receive an error as an argument\n if any tasks pass an error to their callback. If all tasks complete\n successfully, it will receive an object containing their results.\n\n__Example__\n\n async.auto({\n get_data: function(callback){\n // async code to get some data\n },\n make_folder: function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n },\n write_file: ['get_data', 'make_folder', function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, filename);\n }],\n email_link: ['write_file', function(callback, results){\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n }]\n });\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n async.parallel([\n function(callback){\n // async code to get some data\n },\n function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n }\n ],\n function(results){\n async.series([\n function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n },\n email_link: function(callback){\n // once the file is written let's email a link to it...\n }\n ]);\n });\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. Its also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a callback it\n must call on completion.\n\n__Example__\n\n var iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n ]);\n\n node> var iterator2 = iterator();\n 'one'\n node> var iterator3 = iterator2();\n 'two'\n node> iterator3();\n 'three'\n node> var nextfn = iterator2.next();\n node> nextfn();\n 'three'\n\n\n---------------------------------------\n\n\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n // using apply\n\n async.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n ]);\n\n\n // the same process without using apply\n\n async.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n },\n ]);\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n node> var fn = async.apply(sys.puts, 'one');\n node> fn('two', 'three');\n one\n two\n three\n\n---------------------------------------\n\n\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setTimeout(callback, 0),\nwhich means other higher priority events may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n var call_order = [];\n async.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two]\n });\n call_order.push('one')\n\n\n## Utils\n\n\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n results, it has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n var slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n };\n var fn = async.memoize(slow_fn);\n\n // fn can now be used as if it were slow_fn\n fn('some name', function () {\n // callback\n });\n\n\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n var hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n };\n\n node> async.log(hello, 'world');\n 'hello world'\n\n\n---------------------------------------\n\n\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n var hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n };\n\n node> async.dir(hello, 'world');\n {hello: 'world'}\n\n\n---------------------------------------\n\n\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n", - "_id": "async@0.1.22", - "_from": "async" -} diff --git a/rsc/scripts/jsdoc/node_modules/catharsis/LICENSE b/rsc/scripts/jsdoc/node_modules/catharsis/LICENSE deleted file mode 100644 index 9a454a29..00000000 --- a/rsc/scripts/jsdoc/node_modules/catharsis/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) 2012-2013 Jeff Williams - -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/rsc/scripts/jsdoc/node_modules/catharsis/catharsis.js b/rsc/scripts/jsdoc/node_modules/catharsis/catharsis.js deleted file mode 100644 index a9ac7c35..00000000 --- a/rsc/scripts/jsdoc/node_modules/catharsis/catharsis.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Catharsis - * A parser for Google Closure Compiler type expressions, powered by PEG.js. - * - * @author Jeff Williams - * @license MIT License - */ - -'use strict'; - -var parse = require('./lib/parser').parse; -var stringify = require('./lib/stringify'); - -var typeExpressionCache = { - normal: {}, - jsdoc: {} -}; - -var parsedTypeCache = { - normal: {}, - htmlSafe: {} -}; - -function getTypeExpressionCache(options) { - if (options.useCache === false) { - return null; - } else if (options.jsdoc === true) { - return typeExpressionCache.jsdoc; - } else { - return typeExpressionCache.normal; - } -} - -function getParsedTypeCache(options) { - if (options.useCache === false || options.links !== null || options.links !== undefined) { - return null; - } else if (options.htmlSafe === true) { - return parsedTypeCache.htmlSafe; - } else { - return parsedTypeCache.normal; - } -} - -// can't return the original if any of the following are true: -// 1. restringification was requested -// 2. htmlSafe option was requested -// 3. links option was provided -// 4. typeExpression property is missing -function canReturnOriginalExpression(parsedType, options) { - return options.restringify !== true && options.htmlSafe !== true && - (options.links === null || options.links === undefined) && - Object.prototype.hasOwnProperty.call(parsedType, 'typeExpression'); -} - -function cachedParse(expr, options) { - var cache = getTypeExpressionCache(options); - var parsedType; - - if (cache && cache[expr]) { - return cache[expr]; - } else { - parsedType = parse(expr, options); - - Object.defineProperties(parsedType, { - typeExpression: { - value: expr - }, - jsdoc: { - value: options.jsdoc === true ? true : false - } - }); - parsedType = Object.freeze(parsedType); - - if (cache) { - cache[expr] = parsedType; - } - - return parsedType; - } -} - -function cachedStringify(parsedType, options) { - var cache = getParsedTypeCache(options); - var json; - - if (canReturnOriginalExpression(parsedType, options)) { - return parsedType.typeExpression; - } else if (cache) { - json = JSON.stringify(parsedType); - cache[json] = cache[json] || stringify(parsedType, options); - return cache[json]; - } else { - return stringify(parsedType, options); - } -} - -function Catharsis() { - this.Types = require('./lib/types'); -} - -Catharsis.prototype.parse = function(typeExpr, options) { - options = options || {}; - - typeExpr = typeExpr.replace(/[\r\n]/g, '') - .replace(/\s+/g, ' ') - .trim(); - - return cachedParse(typeExpr, options); -}; - -Catharsis.prototype.stringify = function(parsedType, options) { - options = options || {}; - var result; - - result = cachedStringify(parsedType, options); - if (options.validate) { - this.parse(result, options); - } - - return result; -}; - -module.exports = new Catharsis(); diff --git a/rsc/scripts/jsdoc/node_modules/catharsis/lib/parser.js b/rsc/scripts/jsdoc/node_modules/catharsis/lib/parser.js deleted file mode 100644 index 413fa56b..00000000 --- a/rsc/scripts/jsdoc/node_modules/catharsis/lib/parser.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports=function(){function peg$subclass(child,parent){function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor}function SyntaxError(expected,found,offset,line,column){function buildMessage(expected,found){function stringEscape(s){function hex(ch){return ch.charCodeAt(0).toString(16).toUpperCase()}return s.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(ch){return"\\x0"+hex(ch)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(ch){return"\\x"+hex(ch)}).replace(/[\u0180-\u0FFF]/g,function(ch){return"\\u0"+hex(ch)}).replace(/[\u1080-\uFFFF]/g,function(ch){return"\\u"+hex(ch)})}var expectedDesc,foundDesc;switch(expected.length){case 0:expectedDesc="end of input";break;case 1:expectedDesc=expected[0];break;default:expectedDesc=expected.slice(0,-1).join(", ")+" or "+expected[expected.length-1]}foundDesc=found?'"'+stringEscape(found)+'"':"end of input";return"Expected "+expectedDesc+" but "+foundDesc+" found."}this.expected=expected;this.found=found;this.offset=offset;this.line=line;this.column=column;this.name="SyntaxError";this.message=buildMessage(expected,found)}peg$subclass(SyntaxError,Error);function parse(input){var options=arguments.length>1?arguments[1]:{},peg$startRuleFunctions={TypeExpression:peg$parseTypeExpression},peg$startRuleFunction=peg$parseTypeExpression,peg$c0=null,peg$c1="",peg$c2=function(unk){return unk},peg$c3="?",peg$c4='"?"',peg$c5="!",peg$c6='"!"',peg$c7=function(prefix,expr,postfix){if(prefix!==""&&postfix!==""){return null}[prefix,postfix].forEach(function(modifier){if(modifier!==""){expr.nullable=modifier==="?"?true:false}});return expr},peg$c8=function(repeat,lit,opt){var result=lit;if(opt.optional){result.optional=true}if(repeat.repeatable){result.repeatable=true}return result},peg$c9="*",peg$c10='"*"',peg$c11=function(){return{type:Types.AllLiteral}},peg$c12=function(){return{type:Types.NullLiteral}},peg$c13=function(){return{type:Types.UndefinedLiteral}},peg$c14="...",peg$c15='"..."',peg$c16=function(){return{repeatable:true}},peg$c17="=",peg$c18='"="',peg$c19=function(){return{optional:true}},peg$c20="[]",peg$c21='"[]"',peg$c22=function(name){var result;if(!options.jsdoc){return null}result={type:Types.TypeApplication,expression:{type:Types.NameExpression,name:"Array"},applications:[name]};result.applications[0].type=Types.NameExpression;return result},peg$c23=function(exp,appl,opt){var result={};var nameExp={type:Types.NameExpression,name:exp.name};if(appl.length){result.type=Types.TypeApplication;result.expression=nameExp;result.applications=appl}else{result=nameExp}if(exp.repeatable){result.repeatable=true}if(opt.optional){result.optional=true}return result},peg$c24=function(name){if(!options.jsdoc){return null}return name},peg$c25=function(exp,opt){var result={type:Types.NameExpression,name:exp.name,reservedWord:true};if(exp.repeatable){result.repeatable=true}if(opt.optional){result.optional=true}return result},peg$c26=".",peg$c27='"."',peg$c28="<",peg$c29='"<"',peg$c30=">",peg$c31='">"',peg$c32=function(sep,l){if(sep===""&&!options.jsdoc){return null}return l},peg$c33=[],peg$c34=",",peg$c35='","',peg$c36=function(expr,list){var result=[expr];for(var i=0,l=list.length;ipos){peg$cachedPos=0;peg$cachedPosDetails={line:1,column:1,seenCR:false}}peg$cachedPos=pos;advance(peg$cachedPosDetails,peg$cachedPos)}return peg$cachedPosDetails}function peg$fail(expected){if(peg$currPospeg$maxFailPos){peg$maxFailPos=peg$currPos;peg$maxFailExpected=[]}peg$maxFailExpected.push(expected)}function peg$cleanupExpected(expected){var i=0;expected.sort();while(ipeg$currPos){s0=input.charAt(peg$currPos);peg$currPos++}else{s0=null;if(peg$silentFails===0){peg$fail(peg$c271)}}return s0}function peg$parseHexEscapeSequence(){var s0,s1,s2,s3,s4,s5;s0=peg$currPos;if(input.charCodeAt(peg$currPos)===120){s1=peg$c269;peg$currPos++}else{s1=null;if(peg$silentFails===0){peg$fail(peg$c270)}}if(s1!==null){s2=peg$currPos;s3=peg$currPos;s4=peg$parseHexDigit();if(s4!==null){s5=peg$parseHexDigit();if(s5!==null){s4=[s4,s5];s3=s4}else{peg$currPos=s3;s3=peg$c0}}else{peg$currPos=s3;s3=peg$c0}if(s3!==null){s3=input.substring(s2,peg$currPos)}s2=s3;if(s2!==null){peg$reportedPos=s0;s1=peg$c216(s2);if(s1===null){peg$currPos=s0;s0=s1}else{s0=s1}}else{peg$currPos=s0;s0=peg$c0}}else{peg$currPos=s0;s0=peg$c0}return s0}function peg$parseLineContinuation(){var s0,s1,s2;s0=peg$currPos;if(input.charCodeAt(peg$currPos)===92){s1=peg$c212;peg$currPos++}else{s1=null;if(peg$silentFails===0){peg$fail(peg$c213)}}if(s1!==null){s2=peg$parseLineTerminatorSequence();if(s2!==null){peg$reportedPos=s0;s1=peg$c272(s2);if(s1===null){peg$currPos=s0;s0=s1}else{s0=s1}}else{peg$currPos=s0;s0=peg$c0}}else{peg$currPos=s0;s0=peg$c0}return s0}function peg$parse_(){var s0,s1;peg$silentFails++;s0=[];s1=peg$parseWhitespace();while(s1!==null){s0.push(s1);s1=peg$parseWhitespace()}peg$silentFails--;if(s0===null){s1=null;if(peg$silentFails===0){peg$fail(peg$c273)}}return s0}function peg$parse__(){var s0,s1;peg$silentFails++;s0=peg$c1;peg$silentFails--;if(s0===null){s1=null;if(peg$silentFails===0){peg$fail(peg$c274)}}return s0}function peg$parseWhitespace(){var s0;if(peg$c275.test(input.charAt(peg$currPos))){s0=input.charAt(peg$currPos);peg$currPos++}else{s0=null;if(peg$silentFails===0){peg$fail(peg$c276)}}if(s0===null){s0=peg$parseUnicodeZs()}return s0}var Types=require("./types");peg$result=peg$startRuleFunction();if(peg$result!==null&&peg$currPos===input.length){return peg$result}else{peg$cleanupExpected(peg$maxFailExpected);peg$reportedPos=Math.max(peg$currPos,peg$maxFailPos);throw new SyntaxError(peg$maxFailExpected,peg$reportedPos'; - - return result; -}; - -Stringifier.prototype.elements = function(elements) { - if (!elements) { - return ''; - } - - var result = []; - - for (var i = 0, l = elements.length; i < l; i++) { - result.push(this.type(elements[i])); - } - - return '(' + result.join('|') + ')'; -}; - -Stringifier.prototype.name = function(name) { - return name || ''; -}; - -Stringifier.prototype['new'] = function(funcNew) { - return funcNew ? 'new:' + this.type(funcNew) : ''; -}; - -Stringifier.prototype.nullable = function(nullable) { - switch (nullable) { - case true: - return '?'; - case false: - return '!'; - default: - return ''; - } -}; - -Stringifier.prototype.optional = function(optional) { - /*jshint boss: true */ // TODO: remove after JSHint releases the fix for jshint/jshint#878 - if (optional === true) { - return '='; - } else { - return ''; - } -}; - -Stringifier.prototype.params = function(params) { - if (!params || params.length === 0) { - return ''; - } - - var result = []; - - var param; - for (var i = 0, l = params.length; i < l; i++) { - result.push(this.type(params[i])); - } - - return result.join(', '); -}; - -Stringifier.prototype.properties = function(props) { - if (!props) { - return ''; - } - - var result = []; - - for (var i = 0, l = props.length; i < l; i++) { - result.push(this._formatNameAndType(props[i].name, props[i].type)); - } - - return result; -}; - -Stringifier.prototype.result = function(result) { - return result ? ': ' + this.type(result) : ''; -}; - -Stringifier.prototype['this'] = function(funcThis) { - return funcThis ? 'this:' + this.type(funcThis) : ''; -}; - -Stringifier.prototype.type = function(type) { - if (!type) { - return ''; - } - - // nullable comes first - var result = this.nullable(type.nullable); - - // next portion varies by type - switch(type.type) { - case Types.AllLiteral: - result += this._formatNameAndType(type, '*'); - break; - case Types.FunctionType: - result += this._signature(type); - break; - case Types.NullLiteral: - result += this._formatNameAndType(type, 'null'); - break; - case Types.RecordType: - result += this._record(type); - break; - case Types.TypeApplication: - result += this.type(type.expression); - result += this.applications(type.applications); - break; - case Types.UndefinedLiteral: - result += this._formatNameAndType(type, 'undefined'); - break; - case Types.TypeUnion: - result += this.elements(type.elements); - break; - case Types.UnknownLiteral: - result += this._formatNameAndType(type, '?'); - break; - default: - result += this._formatNameAndType(type); - } - - // finally, optionality - result += this.optional(type.optional); - - return result; -}; - -Stringifier.prototype.stringify = Stringifier.prototype.type; - -Stringifier.prototype.key = Stringifier.prototype.type; - -Stringifier.prototype._record = function(type) { - var fields = this._recordFields(type.fields); - - return '{' + fields.join(', ') + '}'; -}; - -Stringifier.prototype._recordFields = function(fields) { - if (!fields) { - return ''; - } - - var result = []; - - var field; - var keyAndValue; - - for (var i = 0, l = fields.length; i < l; i++) { - field = fields[i]; - - keyAndValue = this.key(field.key); - keyAndValue += field.value ? ': ' + this.type(field.value) : ''; - - result.push(keyAndValue); - } - - return result; -}; - -function combineNameAndType(nameString, typeString) { - var separator = (nameString && typeString) ? ':' : ''; - return nameString + separator + typeString; -} - -Stringifier.prototype._formatRepeatable = function(nameString, typeString) { - var open = this._inFunctionSignatureParams ? '...[' : '...'; - var close = this._inFunctionSignatureParams ? ']' : ''; - - return open + combineNameAndType(nameString, typeString) + close; -}; - -Stringifier.prototype._formatNameAndType = function(type, literal) { - var nameString = type.name || literal || ''; - var typeString = type.type ? this.type(type.type) : ''; - var cssClass; - var openTag; - - // replace the type with an HTML link if necessary - if (this._options.links && Object.prototype.hasOwnProperty.call(this._options.links, - nameString)) { - cssClass = this._options.cssClass ? ' class="' + this._options.cssClass + '"' : ''; - - openTag = ''; - nameString = openTag + nameString + ''; - } - - if (type.repeatable === true) { - return this._formatRepeatable(nameString, typeString); - } else { - return combineNameAndType(nameString, typeString); - } -}; - -Stringifier.prototype._signature = function(type) { - var params = []; - var param; - var result; - - // these go within the signature's parens, in this order - var props = [ - 'new', - 'this', - 'params' - ]; - var prop; - - this._inFunctionSignatureParams = true; - for (var i = 0, l = props.length; i < l; i++) { - prop = props[i]; - param = this[prop](type[prop]); - if (param.length > 0) { - params.push(param); - } - } - this._inFunctionSignatureParams = false; - - result = 'function(' + params.join(', ') + ')'; - result += this.result(type.result); - - return result; -}; - - -module.exports = function(type, options) { - return new Stringifier(options).stringify(type); -}; diff --git a/rsc/scripts/jsdoc/node_modules/catharsis/lib/types.js b/rsc/scripts/jsdoc/node_modules/catharsis/lib/types.js deleted file mode 100644 index 017aba6b..00000000 --- a/rsc/scripts/jsdoc/node_modules/catharsis/lib/types.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -module.exports = Object.freeze({ - // `*` - AllLiteral: 'AllLiteral', - // like `blah` in `{blah: string}` - FieldType: 'FieldType', - // like `function(string): string` - FunctionType: 'FunctionType', - // any string literal, such as `string` or `My.Namespace` - NameExpression: 'NameExpression', - // null - NullLiteral: 'NullLiteral', - // like `{foo: string}` - RecordType: 'RecordType', - // like `Array.` - TypeApplication: 'TypeApplication', - // like `(number|string)` - TypeUnion: 'TypeUnion', - // undefined - UndefinedLiteral: 'UndefinedLiteral', - // `?` - UnknownLiteral: 'UnknownLiteral' -}); diff --git a/rsc/scripts/jsdoc/node_modules/catharsis/package.json b/rsc/scripts/jsdoc/node_modules/catharsis/package.json deleted file mode 100644 index 49046e01..00000000 --- a/rsc/scripts/jsdoc/node_modules/catharsis/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "0.5.6", - "name": "catharsis", - "description": "A JavaScript parser for Google Closure Compiler and JSDoc type expressions.", - "author": { - "name": "Jeff Williams", - "email": "jeffrey.l.williams@gmail.com" - }, - "repository": { - "type": "git", - "url": "https://github.com/hegemonic/catharsis" - }, - "bugs": "https://github.com/hegemonic/catharsis/issues", - "main": "catharsis.js", - "devDependencies": { - "mocha": "1.6.0", - "pegjs": "git+ssh://git@github.com:dmajda/pegjs.git#76cc5d55", - "should": "1.2.2", - "uglify-js": "2.2.5", - "underscore": "1.4.4" - }, - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "build": "pegjs ./lib/parser.pegjs", - "prepublish": "pegjs ./lib/parser.pegjs; uglifyjs ./lib/parser.js -o ./lib/parser.js", - "test": "mocha" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/hegemonic/catharsis/raw/master/LICENSE" - } - ], - "readme": "# Catharsis #\n\nA JavaScript parser for\n[Google Closure Compiler](https://developers.google.com/closure/compiler/docs/js-for-compiler#types)\nand [JSDoc](https://github.com/jsdoc3/jsdoc) type expressions.\n\nCatharsis is designed to be:\n\n+ **Accurate**. Catharsis is based on a [PEG.js](http://pegjs.majda.cz/) grammar that's designed to\nhandle any valid type expression. It uses a [Mocha](http://visionmedia.github.com/mocha/) test suite\nto verify the parser's accuracy.\n+ **Fast**. Parse results are cached, so the parser is invoked only when necessary.\n+ **Flexible**. Catharsis can convert parse results back into type expressions. In addition, it can\nparse [JSDoc](https://github.com/jsdoc3/jsdoc)-style type expressions.\n\n\n## Example ##\n\n\tvar catharsis = require('catharsis');\n\n var type;\n var jsdocType;\n var parsedType;\n var parsedJsdocType;\n\n // Google Closure Compiler parsing\n try {\n type = '!Object';\n parsedType = catharsis.parse(type);\n console.log('%j', parsedType); // {\"type\":\"NameExpression,\"name\":\"Object\",\"nullable\":false}\n }\n catch(e) {\n console.error('unable to parse %s: %s', type, e);\n }\n\n // JSDoc-style type expressions enabled\n try {\n jsdocType = 'string[]'; // Closure Compiler expects Array.\n parsedJsdocType = catharsis.parse(jsdocType, {jsdoc: true});\n }\n catch (e) {\n console.error('unable to parse %s: %s', jsdocType, e);\n }\n\n console.log(catharsis.stringify(parsedType)); // !Object\n console.log(catharsis.stringify(parsedJsdocType)); // string[]\n console.log(catharsis.stringify(parsedJsdocType, // Array.\n {restringify: true}));\n\n\nSee the `test/specs/` directory for more examples of Catharsis' parse results.\n\n\n## Methods ##\n\n### parse(typeExpression, options) ###\nParse `typeExpression`, and return the parse results. Throws an error if the type expression cannot\nbe parsed.\n\nWhen called without options, Catharsis attempts to parse type expressions in the same way as\nClosure Compiler. When the `jsdoc` option is enabled, Catharsis can also parse several kinds of\ntype expressions that are permitted in [JSDoc](https://github.com/jsdoc3/jsdoc):\n\n+ The string `function` is treated as a function type with no parameters.\n+ In a function type with repeatable parameters, the names of repeatable parameters are not required\nto be enclosed in square brackets (for example, `function(...foo)` is allowed).\n+ The period may be omitted from type applications. For example, `Array.` and\n`Array` will be parsed in the same way.\n+ You may append `[]` to a name expression (for example, `string[]`) to interpret it as a type\napplication with the expression `Array` (for example, `Array.`).\n+ Name expressions may contain the characters `#`, `~`, `:`, and `/`.\n+ Name expressions may contain a suffix that is similar to a function signature (for example,\n`MyClass(foo, bar)`).\n+ Name expressions may contain a reserved word.\n+ Record types may use types other than name expressions for keys.\n\n#### Parameters ####\n+ `type`: A string containing a Closure Compiler type expression.\n+ `options`: Options for parsing the type expression.\n + `options.jsdoc`: Specifies whether to enable parsing of JSDoc-style type expressions. Defaults\n to `false`.\n + `options.useCache`: Specifies whether to use the cache of parsed types. Defaults to `true`.\n\n#### Returns ####\nAn object containing the parse results. See the `test/specs/` directory for examples of the parse\nresults for different type expressions.\n\nThe object also includes two non-enumerable properties:\n\n+ `jsdoc`: A boolean indicating whether the type expression was parsed with JSDoc support enabled.\n+ `typeExpression`: A string containing the type expression that was parsed.\n\n### stringify(parsedType, options) ###\nStringify `parsedType`, and return the type expression. If validation is enabled, throws an error if\nthe stringified type expression cannot be parsed.\n\n#### Parameters ####\n+ `parsedType`: An object containing a parsed Closure Compiler type expression.\n+ `options`: Options for stringifying the parse results.\n + `options.cssClass`: A CSS class to add to HTML links. Used only if `options.links` is\n provided. By default, no CSS class is added.\n + `options.htmlSafe`: Specifies whether to return an HTML-safe string that replaces left angle\n brackets (`<`) with the corresponding entity (`<`). **Note**: Characters in name expressions\n are not escaped.\n + `options.links`: An object whose keys are name expressions and whose values are URIs. If a\n name expression matches a key in `options.links`, the name expression will be wrapped in an\n HTML `` tag that links to the URI. If `options.cssClass` is specified, the `` tag will\n include a `class` attribute. **Note**: When using this option, parsed types are always\n restringified, and the resulting string is not cached.\n + `options.restringify`: Forces Catharsis to restringify the parsed type. If this option is not\n specified, and the parsed type object includes a `typeExpression` property, Catharsis will\n return the `typeExpression` property without modification when possible. Defaults to `false`.\n + `options.useCache`: Specifies whether to use the cache of stringified parse results. Defaults\n to `true`.\n + `options.validate`: Specifies whether to validate the stringified parse results by attempting\n to parse them as a type expression. If the stringified results are not parsable by default, you\n must also provide the appropriate options to pass to the `parse()` method. Defaults to `false`.\n\n#### Returns ####\nA string containing the type expression.\n\n\n## Installation ##\n\nWith [npm](http://npmjs.org):\n\n npm install catharsis\n\nOr without:\n\n git clone git://github.com/hegemonic/catharsis.git\n\n\n## Roadmap and known issues ##\n\nTake a look at the [issue tracker](https://github.com/hegemonic/catharsis/issues) to see what's in\nstore for Catharsis.\n\nBug reports, feature requests, and pull requests are always welcome! If you're working on a large\npull request, please contact me in advance so I can help things go smoothly.\n\n**Note**: The parse tree's format should not be considered final until Catharsis reaches version\n1.0. I'll do my best to provide release notes for any changes.\n\n\n## Changelog ##\n\n+ 0.5.6 (April 2013):\n + For consistency with Google Closure Library, parentheses are no longer required around type\n unions. (In previous versions, the parentheses could be omitted when JSDoc support was enabled.)\n + For consistency with Google Closure Library, you can now use postfix notation for the `?`\n (nullable) and `!` (non-nullable) modifiers. For example, `?string` and `string?` are now\n treated as equivalent.\n + String literals and numeric literals are now allowed as property names within name\n expressions. For example, the name expression `Foo.\"bar\"` is now parsed correctly.\n+ 0.5.5 (April 2013): Corrected a parsing issue with name expressions that end with a value enclosed\nin parentheses.\n+ 0.5.4 (April 2013):\n + Repeatable literals (for example, `...*`) are now parsed correctly.\n + When JSDoc-style type expressions are enabled, a name expression can now contain a value\n enclosed in parentheses at the end of the name expression (for example, `MyClass(2)`).\n+ 0.5.3 (March 2013): The `parse()` method now correctly parses name expressions that contain\nhyphens.\n+ 0.5.2 (March 2013): The `parse()` method now correctly parses function types when JSDoc-style type\nexpressions are enabled.\n+ 0.5.1 (March 2013): Newlines and extra spaces are now removed from type expressions before they\nare parsed.\n+ 0.5.0 (March 2013):\n + The `parse()` method's `lenient` option has been renamed to `jsdoc`. **Note**: This change is\n not backwards-compatible with previous versions.\n + The `stringify()` method now accepts `cssClass` and `links` options, which you can use to\n add HTML links to a type expression.\n+ 0.4.3 (March 2013):\n + The `stringify()` method no longer caches HTML-safe type expressions as if they were normal\n type expressions.\n + The `stringify()` method's options parameter may now include an `options.restringify`\n property, and the behavior of the `options.useCache` property has changed.\n+ 0.4.2 (March 2013):\n + When lenient parsing is enabled, name expressions can now contain the characters `:` and `/`.\n + When lenient parsing is enabled, a name expression followed by `[]` (for example, `string[]`)\n will be interpreted as a type application with the expression `Array` (for example,\n `Array.`).\n+ 0.4.1 (March 2013):\n + The `parse()` and `stringify()` methods now honor all of the specified options.\n + When lenient parsing is enabled, name expressions can now contain a reserved word.\n+ 0.4.0 (March 2013):\n + Catharsis now supports a lenient parsing option that can parse several kinds of malformed type\n expressions. See the documentation for details.\n + The objects containing parse results are now frozen.\n + The objects containing parse results now have two non-enumerable properties:\n + `lenient`: A boolean indicating whether the type expression was parsed in lenient mode.\n + `typeExpression`: A string containing the original type expression.\n + The `stringify()` method now honors the `useCache` option. If a parsed type includes a\n `typeExpression` property, and `useCache` is not set to `false`, the stringified type will be\n identical to the original type expression.\n+ 0.3.1 (March 2013): Type expressions that begin with a reserved word, such as `integer`, are now\nparsed correctly.\n+ 0.3.0 (March 2013):\n + The `parse()` and `stringify()` methods are now synchronous, and the `parseSync()` and\n `stringifySync()` methods have been removed. **Note**: This change is not backwards-compatible\n with previous versions.\n + The parse results now use a significantly different format from previous versions. The new\n format is more expressive and is similar, but not identical, to the format used by the\n [doctrine](https://github.com/Constellation/doctrine) parser. **Note**: This change is not\n backwards-compatible with previous versions.\n + Name expressions that contain a reserved word now include a `reservedWord: true` property.\n + Union types that are optional or nullable, or that can be passed a variable number of times,\n are now parsed and stringified correctly.\n + Optional function types and record types are now parsed and stringified correctly.\n + Function types now longer include `new` or `this` properties unless the properties are defined\n in the type expression. In addition, the `new` and `this` properties can now use any type\n expression.\n + In record types, the key for a field type can now use any type expression.\n + Standalone single-character literals, such as ALL (`*`), are now parsed and stringified\n correctly.\n + `null` and `undefined` literals with additional properties, such as `repeatable`, are now\n stringified correctly.\n+ 0.2.0 (November 2012):\n + Added `stringify()` and `stringifySync()` methods, which convert a parsed type to a type\n expression.\n + Simplified the parse results for function signatures. **Note**: This change is not\n backwards-compatible with previous versions.\n + Corrected minor errors in README.md.\n+ 0.1.1 (November 2012): Added `opts` argument to `parse()` and `parseSync()` methods. **Note**: The\nchange to `parse()` is not backwards-compatible with previous versions.\n+ 0.1.0 (November 2012): Initial release.\n\n## License ##\n\n[MIT license](https://github.com/hegemonic/catharsis/blob/master/LICENSE).\n", - "readmeFilename": "README.md", - "_id": "catharsis@0.5.6", - "dist": { - "shasum": "210a0cfa23c5d09fa994d6fafe1a76383c170cbb" - }, - "_from": "catharsis@0.5.6", - "_resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.5.6.tgz" -} diff --git a/rsc/scripts/jsdoc/node_modules/crypto-browserify/index.js b/rsc/scripts/jsdoc/node_modules/crypto-browserify/index.js deleted file mode 100644 index a6762ed4..00000000 --- a/rsc/scripts/jsdoc/node_modules/crypto-browserify/index.js +++ /dev/null @@ -1,68 +0,0 @@ -var sha = require('./sha') -var rng = require('./rng') - -var algorithms = { - sha1: { - hex: sha.hex_sha1, - binary: sha.b64_sha1, - ascii: sha.str_sha1 - } -} - -function error () { - var m = [].slice.call(arguments).join(' ') - throw new Error([ - m, - 'we accept pull requests', - 'http://github.com/dominictarr/crypto-browserify' - ].join('\n')) -} - -exports.createHash = function (alg) { - alg = alg || 'sha1' - if(!algorithms[alg]) - error('algorithm:', alg, 'is not yet supported') - var s = '' - var _alg = algorithms[alg] - return { - update: function (data) { - s += data - return this - }, - digest: function (enc) { - enc = enc || 'binary' - var fn - if(!(fn = _alg[enc])) - error('encoding:', enc , 'is not yet supported for algorithm', alg) - var r = fn(s) - s = null //not meant to use the hash after you've called digest. - return r - } - } -} - -exports.randomBytes = function(size, callback) { - if (callback && callback.call) { - try { - callback.call(this, undefined, rng(size)); - } catch (err) { callback(err); } - } else { - return rng(size); - } -} - -// the least I can do is make error messages for the rest of the node.js/crypto api. -;['createCredentials' -, 'createHmac' -, 'createCypher' -, 'createCypheriv' -, 'createDecipher' -, 'createDecipheriv' -, 'createSign' -, 'createVerify' -, 'createDeffieHellman' -, 'pbkdf2'].forEach(function (name) { - exports[name] = function () { - error('sorry,', name, 'is not implemented yet') - } -}) diff --git a/rsc/scripts/jsdoc/node_modules/crypto-browserify/package.json b/rsc/scripts/jsdoc/node_modules/crypto-browserify/package.json deleted file mode 100644 index 99a6930c..00000000 --- a/rsc/scripts/jsdoc/node_modules/crypto-browserify/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "author": { - "name": "Dominic Tarr", - "email": "dominic.tarr@gmail.com", - "url": "dominictarr.com" - }, - "name": "crypto-browserify", - "description": "partial implementation of crypto for the browser", - "version": "0.1.1", - "homepage": "https://github.com/dominictarr/crypto-browserify", - "repository": { - "url": "" - }, - "scripts": { - "test": "node test/simple.js" - }, - "engines": { - "node": "*" - }, - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "readme": "# crypto-browserify\n\nA (partial) port of `crypto` to the browser.\n\nBasically, I found some crypto implemented in JS lieing on the internet somewhere\nand wrapped it in the part of the `crypto` api that I am currently using.\n\nIn a way that will be compatible with [browserify](https://github.com/substack/node-browserify/).\n\nI will extend this if I need more features, or if anyone else wants to extend this,\nI will add you as a maintainer.\n\nProvided that you agree that it should replicate the [node.js/crypto](http://nodejs.org/api/crypto.html) api exactly, of course.\n\n", - "_id": "crypto-browserify@0.1.1", - "dist": { - "shasum": "251b240c6bd0e95db0654fbc8b178b855cbef45e" - }, - "_from": "crypto-browserify@git://github.com/dominictarr/crypto-browserify.git#95c5d505" -} diff --git a/rsc/scripts/jsdoc/node_modules/crypto-browserify/rng.js b/rsc/scripts/jsdoc/node_modules/crypto-browserify/rng.js deleted file mode 100644 index 2160788a..00000000 --- a/rsc/scripts/jsdoc/node_modules/crypto-browserify/rng.js +++ /dev/null @@ -1,37 +0,0 @@ -// Original code adapted from Robert Kieffer. -// details at https://github.com/broofa/node-uuid -(function() { - var _global = this; - - var mathRNG, whatwgRNG; - - // NOTE: Math.random() does not guarantee "cryptographic quality" - mathRNG = function(size) { - var bytes = new Array(size); - var r; - - for (var i = 0, r; i < size; i++) { - if ((i & 0x03) == 0) r = Math.random() * 0x100000000; - bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return bytes; - } - - // currently only available in webkit-based browsers. - if (_global.crypto && crypto.getRandomValues) { - var _rnds = new Uint32Array(4); - whatwgRNG = function(size) { - var bytes = new Array(size); - crypto.getRandomValues(_rnds); - - for (var c = 0 ; c < size; c++) { - bytes[c] = _rnds[c >> 2] >>> ((c & 0x03) * 8) & 0xff; - } - return bytes; - } - } - - module.exports = whatwgRNG || mathRNG; - -}()) \ No newline at end of file diff --git a/rsc/scripts/jsdoc/node_modules/crypto-browserify/sha.js b/rsc/scripts/jsdoc/node_modules/crypto-browserify/sha.js deleted file mode 100644 index 4f9cc3e9..00000000 --- a/rsc/scripts/jsdoc/node_modules/crypto-browserify/sha.js +++ /dev/null @@ -1,210 +0,0 @@ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined - * in FIPS PUB 180-1 - * Version 2.1a Copyright Paul Johnston 2000 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for details. - */ - -exports.hex_sha1 = hex_sha1; -exports.b64_sha1 = b64_sha1; -exports.str_sha1 = str_sha1; -exports.hex_hmac_sha1 = hex_hmac_sha1; -exports.b64_hmac_sha1 = b64_hmac_sha1; -exports.str_hmac_sha1 = str_hmac_sha1; - -/* - * Configurable variables. You may need to tweak these to be compatible with - * the server-side, but the defaults work in most cases. - */ -var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ -var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ -var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ - -/* - * These are the functions you'll usually want to call - * They take string arguments and return either hex or base-64 encoded strings - */ -function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} -function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} -function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} -function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} -function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} -function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} - -/* - * Perform a simple self-test to see if the VM is working - */ -function sha1_vm_test() -{ - return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; -} - -/* - * Calculate the SHA-1 of an array of big-endian words, and a bit length - */ -function core_sha1(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << (24 - len % 32); - x[((len + 64 >> 9) << 4) + 15] = len; - - var w = Array(80); - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - var e = -1009589776; - - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - var olde = e; - - for(var j = 0; j < 80; j++) - { - if(j < 16) w[j] = x[i + j]; - else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); - var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), - safe_add(safe_add(e, w[j]), sha1_kt(j))); - e = d; - d = c; - c = rol(b, 30); - b = a; - a = t; - } - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - e = safe_add(e, olde); - } - return Array(a, b, c, d, e); - -} - -/* - * Perform the appropriate triplet combination function for the current - * iteration - */ -function sha1_ft(t, b, c, d) -{ - if(t < 20) return (b & c) | ((~b) & d); - if(t < 40) return b ^ c ^ d; - if(t < 60) return (b & c) | (b & d) | (c & d); - return b ^ c ^ d; -} - -/* - * Determine the appropriate additive constant for the current iteration - */ -function sha1_kt(t) -{ - return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : - (t < 60) ? -1894007588 : -899497514; -} - -/* - * Calculate the HMAC-SHA1 of a key and some data - */ -function core_hmac_sha1(key, data) -{ - var bkey = str2binb(key); - if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); - - var ipad = Array(16), opad = Array(16); - for(var i = 0; i < 16; i++) - { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } - - var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); - return core_sha1(opad.concat(hash), 512 + 160); -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} - -/* - * Convert an 8-bit or 16-bit string to an array of big-endian words - * In 8-bit function, characters >255 have their hi-byte silently ignored. - */ -function str2binb(str) -{ - var bin = Array(); - var mask = (1 << chrsz) - 1; - for(var i = 0; i < str.length * chrsz; i += chrsz) - bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); - return bin; -} - -/* - * Convert an array of big-endian words to a string - */ -function binb2str(bin) -{ - var str = ""; - var mask = (1 << chrsz) - 1; - for(var i = 0; i < bin.length * 32; i += chrsz) - str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); - return str; -} - -/* - * Convert an array of big-endian words to a hex string. - */ -function binb2hex(binarray) -{ - var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; - var str = ""; - for(var i = 0; i < binarray.length * 4; i++) - { - str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + - hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); - } - return str; -} - -/* - * Convert an array of big-endian words to a base-64 string - */ -function binb2b64(binarray) -{ - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - var str = ""; - for(var i = 0; i < binarray.length * 4; i += 3) - { - var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) - | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) - | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); - for(var j = 0; j < 4; j++) - { - if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; - else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); - } - } - return str; -} - diff --git a/rsc/scripts/jsdoc/node_modules/js2xmlparser/LICENSE.md b/rsc/scripts/jsdoc/node_modules/js2xmlparser/LICENSE.md deleted file mode 100644 index 0cb547eb..00000000 --- a/rsc/scripts/jsdoc/node_modules/js2xmlparser/LICENSE.md +++ /dev/null @@ -1,16 +0,0 @@ -js2xmlparser is licensed under the MIT license: - -> Copyright (C) 2012 Michael Kourlas -> -> 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/rsc/scripts/jsdoc/node_modules/js2xmlparser/lib/js2xmlparser.js b/rsc/scripts/jsdoc/node_modules/js2xmlparser/lib/js2xmlparser.js deleted file mode 100644 index cf8110f1..00000000 --- a/rsc/scripts/jsdoc/node_modules/js2xmlparser/lib/js2xmlparser.js +++ /dev/null @@ -1,223 +0,0 @@ -var xmlDeclaration = true; -var xmlVersion = "1.0"; -var xmlEncoding = "UTF-8"; -var attributeString = "@"; -var valueString = "#"; -var prettyPrinting = true; -var indentString = "\t"; - -module.exports = function (root, data, options) { - - return toXML(init(root, data, options)); -}; - -// Initialization -var init = function(root, data, options) { - - // Error checking for root element - if (typeof root !== "string") - throw new Error("root element must be a string"); - - // Error checking and variable initialization for options - if (typeof options === "object" && options !== null) { - - if ("declaration" in options) { - - if ("include" in options.declaration) { - - if (typeof options.declaration.include === "boolean") - xmlDeclaration = options.declaration.include; - else - throw new Error("declaration.include option must be a boolean"); - } - - if ("encoding" in options.declaration) { - - if (typeof options.declaration.encoding === "string" || options.declaration.encoding === null) - xmlEncoding = options.declaration.encoding; - else - throw new Error("declaration.encoding option must be a string or null"); - } - } - if ("attributeString" in options) { - - if (typeof options.attributeString === "string") - attributeString = options.attributeString; - else - throw new Error("attributeString option must be a string"); - } - if ("valueString" in options) { - - if (typeof options.valueString === "string") - valueString = options.valueString; - else - throw new Error("valueString option must be a string"); - } - if ("prettyPrinting" in options) { - - if ("enabled" in options.prettyPrinting) { - - if (typeof options.prettyPrinting.enabled === "boolean") - prettyPrinting = options.prettyPrinting.enabled; - else - throw new Error("prettyPrinting.enabled option must be a boolean"); - } - - if ("indentString" in options.prettyPrinting) { - - if (typeof options.prettyPrinting.indentString === "string") - indentString = options.prettyPrinting.indentString; - else - throw new Error("prettyPrinting.indentString option must be a string"); - } - } - } - - // Error checking and variable initialization for data - if (typeof data !== "string" && typeof data !== "object") - throw new Error("data must be an object or a string"); - - if (typeof data === "string") - data = JSON.parse(data); - - var tempData = {}; - tempData[root] = data; // Add root element to object - - return tempData; -}; - -// Convert object to XML -var toXML = function(object) { - - // Initialize arguments, if necessary - var xml = arguments[1] || ""; - var level = arguments[2] || 0; - - for (var property in object) { - - // Arrays - if (Object.prototype.toString.call(object[property]) === "[object Array]") { - - // Create separate object for each array element and pass to this function - for (var i = 0; i < object[property].length; i++) { - - var obj = {}; - obj[property] = object[property][i]; - - xml = toXML(obj, xml, level); - } - } - // JSON-type objects with properties - else if (Object.prototype.toString.call(object[property]) === "[object Object]") { - - xml += addIndent("<" + property, level); - - // Add attributes - var lengthExcludingAttributes = Object.keys(object[property]).length; - if (Object.prototype.toString.call(object[property][attributeString]) === "[object Object]") { - - lengthExcludingAttributes -= 1; - for (var attribute in object[property][attributeString]) - xml += " " + attribute + "=\"" + toString(object[property][attributeString][attribute]) + "\""; - } - - if (lengthExcludingAttributes === 0) // Empty object - xml += addBreak("/>"); - else if (lengthExcludingAttributes === 1 && valueString in object[property]) // Value string only - xml += addBreak(">" + toString(object[property][valueString]) + ""); - else { // Object with properties - - xml += addBreak(">"); - - // Create separate object for each property and pass to this function - for (var subProperty in object[property]) { - - if (subProperty !== attributeString) { - - var tempObject = {}; - tempObject[subProperty] = object[property][subProperty]; - - xml = toXML(tempObject, xml, level + 1); - } - } - - xml += addBreak(addIndent("", level)); - } - } - // Everything else - else { - - xml += addBreak(addIndent("<" + property + ">" + toString(object[property]) + "", level)); - } - } - - // Finalize XML at end of process - if (level === 0) { - - // Remove extra line break at end of file - xml = xml.substring(0, xml.length - 1); - - // Add XML declaration - if (xmlDeclaration) - if (xmlEncoding === null) - xml = addBreak("") + xml; - else - xml = addBreak("") + xml; - } - - return xml; -}; - -// Add indenting to data for pretty printing -var addIndent = function(data, level) { - - if (prettyPrinting) { - - var indent = ""; - for (var i = 0; i < level; i++) { - indent += indentString; - } - data = indent + data; - } - - return data; -}; - -// Add line break to data for pretty printing -var addBreak = function(data) { - - return prettyPrinting ? data + "\n" : data; -}; - -// Convert anything into a valid XML string representation -var toString = function(data) { - - // Recursive function used to handle nested functions - var functionHelper = function(data) { - - if (Object.prototype.toString.call(data) === "[object Function]") - return (data() === undefined) ? data.toString() : functionHelper(data()); - else - return data; - }; - - // Functions - if (Object.prototype.toString.call(data) === "[object Function]") - data = functionHelper(data); - // Empty objects - else if (Object.prototype.toString.call(data) === "[object Object]" && Object.keys(data).length === 0) - data = ""; - - // Cast data to string - if (typeof data !== "string") - data = data.toString(); - - // Escape illegal XML characters - data = data.replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); - - return data; -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/node_modules/js2xmlparser/package.json b/rsc/scripts/jsdoc/node_modules/js2xmlparser/package.json deleted file mode 100644 index d4384f36..00000000 --- a/rsc/scripts/jsdoc/node_modules/js2xmlparser/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "js2xmlparser", - "description": "Parses JavaScript objects into XML", - "keywords": [ - "convert", - "converter", - "js", - "json", - "object", - "objects", - "parse", - "parser", - "xml" - ], - "homepage": "http://www.kourlas.net", - "version": "0.1.0", - "author": { - "name": "Michael Kourlas", - "email": "michaelkourlas@gmail.com" - }, - "main": "./lib/js2xmlparser.js", - "repository": { - "type": "git", - "url": "git://github.com/michaelkourlas/node-js2xmlparser.git" - }, - "license": "MIT", - "readme": "# node-js2xmlparser #\r\n\r\n## Overview ##\r\n\r\njs2xmlparser is a Node.js module that parses JavaScript objects into XML.\r\n\r\n## Features ##\r\n\r\nSince XML is a data-interchange format, js2xmlparser is designed primarily for JSON-type objects, arrays and primitive\r\ndata types, like many of the other JavaScript to XML parsers currently available for Node.js.\r\n\r\nHowever, js2xmlparser is capable of parsing any object, including native JavaScript objects such as Date and RegExp, by\r\ntaking advantage of each object's toString function. Functions are a special case where the return value of the function\r\nitself is used instead of the toString function, if available.\r\n\r\njs2xmlparser also supports a number of constructs unique to XML:\r\n\r\n* attributes (through a unique attribute property in objects)\r\n* mixed content (through a unique value property in objects)\r\n* multiple elements with the same name (through arrays)\r\n\r\njs2xmlparser can also pretty-print the XML it outputs with the option of customizing the indent string.\r\n\r\n## Installation ##\r\n\r\nThe easiest way to install js2xmlparser is to use npm: `npm install js2xmlparser`.\r\n\r\nAlternatively, you may download the source from GitHub and copy it to a folder named \"js2xmlparser\" within your\r\n\"node_modules\" directory.\r\n\r\n## Usage ##\r\n\r\nThe js2xmlparser module contains one function which takes the following arguments:\r\n\r\n* `root` - string containing the root element of the XML\r\n* `data` - object or JSON string to be converted to XML\r\n* `options` - object containing options (optional)\r\n * `declaration` - XML declaration options object (optional)\r\n * `include` - boolean representing whether an XML declaration is included (optional, default: true)\r\n * `encoding` - string representing the XML encoding for the corresponding attribute in the declaration; a value\r\n of null represents no encoding attribute (optional, default: \"UTF-8\")\r\n * `attributeString` - string containing the attribute property (optional, default: \"@\")\r\n * `valueString` - string containing the value property (optional, default: \"#\")\r\n * `prettyPrinting` - pretty-printing options object (optional)\r\n * `enabled` - boolean representing whether pretty-printing is enabled (optional, default: true)\r\n * `indentString` - string representing the indent (optional, default: \"\\t\")\r\n\r\n## Example ##\r\n\r\nThe following example illustrates the basic usage of js2xmlparser:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"firstName\": \"John\",\r\n \"lastName\": \"Smith\"\r\n };\r\n\r\n console.log(js2xmlparser(\"person\", data));\r\n\r\n > \r\n > \r\n > John\r\n > Smith\r\n > \r\n\r\nHere's a more complex example that builds on the first:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"firstName\": \"John\",\r\n \"lastName\": \"Smith\",\r\n \"dateOfBirth\": new Date(1964, 07, 26),\r\n \"address\": {\r\n \"@\": {\r\n \"type\": \"home\"\r\n },\r\n \"streetAddress\": \"3212 22nd St\",\r\n \"city\": \"Chicago\",\r\n \"state\": \"Illinois\",\r\n \"zip\": 10000\r\n },\r\n \"phone\": [\r\n {\r\n \"@\": {\r\n \"type\": \"home\"\r\n },\r\n \"#\": \"123-555-4567\"\r\n },\r\n {\r\n \"@\": {\r\n \"type\": \"cell\"\r\n },\r\n \"#\": \"456-555-7890\"\r\n }\r\n ],\r\n \"email\": function() {return \"john@smith.com\";}\r\n }\r\n\r\n console.log(js2xmlparser(\"person\", data));\r\n\r\n > \r\n > \r\n > John\r\n > Smith\r\n > Wed Aug 26 1964 00:00:00 GMT-0400 (Eastern Daylight Time)\r\n >
\r\n > 3212 22nd St\r\n > Chicago\r\n > Illinois\r\n > 10000\r\n >
\r\n > 123-555-4567\r\n > 456-555-7890\r\n > john@smith.com\r\n >
", - "_id": "js2xmlparser@0.1.0", - "_from": "js2xmlparser" -} diff --git a/rsc/scripts/jsdoc/node_modules/jsdoc b/rsc/scripts/jsdoc/node_modules/jsdoc deleted file mode 100644 index bc705d5f..00000000 --- a/rsc/scripts/jsdoc/node_modules/jsdoc +++ /dev/null @@ -1 +0,0 @@ -../lib/jsdoc \ No newline at end of file diff --git a/rsc/scripts/jsdoc/node_modules/jshint/LICENSE b/rsc/scripts/jsdoc/node_modules/jshint/LICENSE deleted file mode 100644 index 0b310fe7..00000000 --- a/rsc/scripts/jsdoc/node_modules/jshint/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -** Licensed Under ** - - The MIT License - http://www.opensource.org/licenses/mit-license.php diff --git a/rsc/scripts/jsdoc/node_modules/jshint/package.json b/rsc/scripts/jsdoc/node_modules/jshint/package.json deleted file mode 100644 index 75d12516..00000000 --- a/rsc/scripts/jsdoc/node_modules/jshint/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "jshint", - "version": "0.9.1", - "description": "A CLI for JSHint", - "homepage": "http://github.com/jshint/node-jshint", - "author": { - "name": "Brent Lintner", - "email": "brent.lintner@gmail.com", - "url": "http://github.com/brentlintner" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/mit-license.php" - } - ], - "bin": { - "jshint": "./bin/hint" - }, - "main": "packages/jshint/jshint", - "files": [ - "packages/jshint/README.markdown", - "packages/jshint/jshint.js", - "README.md", - "LICENSE", - "bin/hint", - "lib" - ], - "dependencies": { - "cli": "0.4.3", - "minimatch": "0.0.x" - }, - "devDependencies": { - "jasmine-node": "1.0.x" - }, - "preferGlobal": true, - "readme": "# node-jshint\n\nA command line interface and npm package for jshint.\n\n## Install\n\nTo use jshint from any location (for npm v1.x) you need to install using the global (-g) flag.\n\n npm install -g jshint\n\n## Usage\n\n jshint -h\n\nYou can also require JSHint itself as a module.\n\n var jshint = require('jshint');\n\nNote: If you are using npm v1.x be sure to install jshint locally (without the -g flag) or link it globally.\n\n## Text Editor Plugins\n\n* [gedit-node-jshint](https://github.com/niftylettuce/gedit-node-jshint) - Simply use CTRL+J in gedit to run JSHint using `node-jshint`.\n* [vim syntastic](https://github.com/scrooloose/syntastic) - Run node-jshint at each file save.\n* [sublime-jshint](https://github.com/uipoet/sublime-jshint) - `F7` or `command-B` on any .js file. `F4` next error line,column. `shift-F4` previous error line,column.\n\n## Custom Reporters\n\nSpecify a custom reporter module (see example/reporter.js).\n\n --reporter path/to/reporter.js\n\nUse a jslint compatible xml reporter.\n\n --jslint-reporter\n\nShow additional non-error data generated by jshint (unused globals etc).\n\n --show-non-errors\n\n## Configuration Options\n\n**Note:** This behavior described below is very different from versions prior to `0.6`.\n\nThe CLI uses the default options that come with JSHint. \n\nOnly one extra option is unique to node-jshint: `globals` \nallows you to define an object of globals that get ignored for every file.\nTo see an example you can look at how whitelisted globals are defined\nin the [jshint code](https://github.com/jshint/jshint/blob/c047ea1b01097fcc220fcd1a55c41f67ae2e6e81/jshint.js#L556)\n\nTo have your own configuration apply, there are several methods you can use:\n\n### Specify Manually\n\nSetting the `--config=/path/to/your/config` command line option to specify your own configuration file outside of the directory tree for your project.\n\n### Within your Project's Directory Tree\n\nWhen the CLI is called, and a configuration file isn't specified already, `node-jshint` will attempt to locate one for you starting in `pwd`. (or \"present working directory\") If this does not yield a `.jshintrc` file, it will move one level up (`..`) the directory tree all the way up to the filesystem root. If a file is found, it stops immediately and uses that set of configuration.\n\nThis setup allows you to set up **one** configuration file for your entire project. (place it in the root folder) As long as you run `jshint` from anywhere within your project directory tree, the same configuration file will be used.\n\n### Home Directory\n\nIf all the methods above do not yield a `.jshintrc` to use, the last place that will be checked is your user's `$HOME` directory.\n\n## File Extensions\n\nDefault extension for files is \".js\". If you want to use JSHint with other file extensions (.json), you need to pass this extra extension as an option :\n\n --extra-ext .json\n\n## Ignoring Files and Directories\n\nIf there is a .jshintignore file in your project's directory tree, (also provided you run `jshint` from within your project's directory) then any directories or files specified will be skipped over. (behaves just like a `.gitignore` file)\n\n**Note:** Pattern matching uses minimatch, with the nocase [option](https://github.com/isaacs/minimatch). When there is no match, it performs a left side match (when no forward slashes present and path is a directory).\n\n## Installing dependencies for development\n\n ./configure\n\n## Build Commands\n\n jake -T\n\n## Project Guidelines\n\n* All tests are passing.\n* No (new) JSHint errors are introduced.\n", - "_id": "jshint@0.9.1", - "dist": { - "shasum": "ea05fb7d6dae4f2d0d0392ad89b06f7b72eb497e" - }, - "_from": "jshint" -} diff --git a/rsc/scripts/jsdoc/node_modules/jshint/packages/jshint/jshint.js b/rsc/scripts/jsdoc/node_modules/jshint/packages/jshint/jshint.js deleted file mode 100644 index 53724f5c..00000000 --- a/rsc/scripts/jsdoc/node_modules/jshint/packages/jshint/jshint.js +++ /dev/null @@ -1,4832 +0,0 @@ -/*! - * JSHint, by JSHint Community. - * - * Licensed under the same slightly modified MIT license that JSLint is. - * It stops evil-doers everywhere. - * - * JSHint is a derivative work of JSLint: - * - * Copyright (c) 2002 Douglas Crockford (www.JSLint.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 shall be used for Good, not Evil. - * - * 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. - * - * JSHint was forked from the 2010-12-16 edition of JSLint. - * - */ - -/* - JSHINT is a global function. It takes two parameters. - - var myResult = JSHINT(source, option); - - The first parameter is either a string or an array of strings. If it is a - string, it will be split on '\n' or '\r'. If it is an array of strings, it - is assumed that each string represents one line. The source can be a - JavaScript text or a JSON text. - - The second parameter is an optional object of options which control the - operation of JSHINT. Most of the options are booleans: They are all - optional and have a default value of false. One of the options, predef, - can be an array of names, which will be used to declare global variables, - or an object whose keys are used as global names, with a boolean value - that determines if they are assignable. - - If it checks out, JSHINT returns true. Otherwise, it returns false. - - If false, you can inspect JSHINT.errors to find out the problems. - JSHINT.errors is an array of objects containing these members: - - { - line : The line (relative to 1) at which the lint was found - character : The character (relative to 1) at which the lint was found - reason : The problem - evidence : The text line in which the problem occurred - raw : The raw message before the details were inserted - a : The first detail - b : The second detail - c : The third detail - d : The fourth detail - } - - If a fatal error was found, a null will be the last element of the - JSHINT.errors array. - - You can request a data structure which contains JSHint's results. - - var myData = JSHINT.data(); - - It returns a structure with this form: - - { - errors: [ - { - line: NUMBER, - character: NUMBER, - reason: STRING, - evidence: STRING - } - ], - functions: [ - name: STRING, - line: NUMBER, - character: NUMBER, - last: NUMBER, - lastcharacter: NUMBER, - param: [ - STRING - ], - closure: [ - STRING - ], - var: [ - STRING - ], - exception: [ - STRING - ], - outer: [ - STRING - ], - unused: [ - STRING - ], - global: [ - STRING - ], - label: [ - STRING - ] - ], - globals: [ - STRING - ], - member: { - STRING: NUMBER - }, - unused: [ - { - name: STRING, - line: NUMBER - } - ], - implieds: [ - { - name: STRING, - line: NUMBER - } - ], - urls: [ - STRING - ], - json: BOOLEAN - } - - Empty arrays will not be included. - -*/ - -/*jshint - evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true, - undef: true, maxlen: 100, indent: 4, quotmark: double, unused: true -*/ - -/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)", - "(breakage)", "(character)", "(context)", "(error)", "(explicitNewcap)", "(global)", - "(identifier)", "(last)", "(lastcharacter)", "(line)", "(loopage)", "(metrics)", - "(name)", "(onevar)", "(params)", "(scope)", "(statement)", "(verb)", "(tokens)", "(catch)", - "*", "+", "++", "-", "--", "\/", "<", "<=", "==", - "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax, - __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio, - Autocompleter, Asset, Boolean, Builder, Buffer, Browser, Blob, COM, CScript, Canvas, - CustomAnimation, Class, Control, ComplexityCount, Chain, Color, Cookie, Core, DataView, Date, - Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMEvent, DOMReady, DOMParser, - Drag, E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event, - Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form, - FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey, - HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement, - HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDirectoryElement, - HTMLDivElement, HTMLDListElement, HTMLFieldSetElement, - HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement, - HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement, - HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement, - HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement, - HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement, - HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement, - HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement, - HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement, - HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement, - HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement, - HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement, - Iframe, IframeShim, Image, importScripts, Int16Array, Int32Array, Int8Array, - Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E, - MAX_VALUE, MIN_VALUE, Map, Mask, Math, MenuItem, MessageChannel, MessageEvent, MessagePort, - MoveAnimation, MooTools, MutationObserver, NaN, Native, NEGATIVE_INFINITY, Node, NodeFilter, - Number, Object, ObjectRange, - Option, Options, OverText, PI, POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, - RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation, Set, - SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion, - ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller, - Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables, - SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template, - Timer, Tips, Type, TypeError, Toggle, Try, "use strict", unescape, URI, URIError, URL, - VBArray, WeakMap, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XMLSerializer, - XPathEvaluator, XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, - "\\", a, abs, addEventListener, address, alert, apply, applicationCache, arguments, arity, - asi, atob, b, basic, basicToken, bitwise, blacklist, block, blur, boolOptions, boss, - browser, btoa, c, call, callee, caller, camelcase, cases, charAt, charCodeAt, character, - clearInterval, clearTimeout, close, closed, closure, comment, complexityCount, condition, - confirm, console, constructor, content, couch, create, css, curly, d, data, datalist, dd, debug, - decodeURI, decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document, - dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent, elem, - eqeq, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil, - ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus, forEach, - forin, fragment, frames, from, fromCharCode, fud, funcscope, funct, function, functions, - g, gc, getComputedStyle, getRow, getter, getterToken, GLOBAL, global, globals, globalstrict, - hasOwnProperty, help, history, i, id, identifier, immed, implieds, importPackage, include, - indent, indexOf, init, ins, internals, instanceOf, isAlpha, isApplicationRunning, isArray, - isDigit, isFinite, isNaN, iterator, java, join, jshint, - JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastcharacter, lastsemic, laxbreak, - laxcomma, latedef, lbp, led, left, length, line, load, loadClass, localStorage, location, - log, loopfunc, m, match, max, maxcomplexity, maxdepth, maxerr, maxlen, maxstatements, maxparams, - member, message, meta, module, moveBy, moveTo, mootools, multistr, name, navigator, new, newcap, - nestedBlockDepth, noarg, node, noempty, nomen, nonew, nonstandard, nud, onbeforeunload, onblur, - onerror, onevar, onecase, onfocus, onload, onresize, onunload, open, openDatabase, openURL, - opener, opera, options, outer, param, parent, parseFloat, parseInt, passfail, plusplus, - postMessage, pop, predef, print, process, prompt, proto, prototype, prototypejs, provides, push, - quit, quotmark, range, raw, reach, reason, regexp, readFile, readUrl, regexdash, - removeEventListener, replace, report, require, reserved, resizeBy, resizeTo, resolvePath, - resumeUpdates, respond, rhino, right, runCommand, scroll, scope, screen, scripturl, scrollBy, - scrollTo, scrollbar, search, seal, self, send, serialize, sessionStorage, setInterval, setTimeout, - setter, setterToken, shift, slice, smarttabs, sort, spawn, split, statement, statementCount, stack, - status, start, strict, sub, substr, supernew, shadow, supplant, sum, sync, test, toLowerCase, - toString, toUpperCase, toint32, token, tokens, top, trailing, type, typeOf, Uint16Array, - Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis, value, valueOf, var, vars, - version, verifyMaxParametersPerFunction, verifyMaxStatementsPerFunction, - verifyMaxComplexityPerFunction, verifyMaxNestedBlockDepthPerFunction, WebSocket, withstmt, white, - window, windows, Worker, worker, wsh, yui, YUI, Y, YUI_config*/ - -/*global exports: false */ - -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSHINT function itself. - -var JSHINT = (function () { - "use strict"; - - var anonname, // The guessed name for anonymous functions. - -// These are operators that should not be used with the ! operator. - - bang = { - "<" : true, - "<=" : true, - "==" : true, - "===": true, - "!==": true, - "!=" : true, - ">" : true, - ">=" : true, - "+" : true, - "-" : true, - "*" : true, - "/" : true, - "%" : true - }, - - // These are the JSHint boolean options. - boolOptions = { - asi : true, // if automatic semicolon insertion should be tolerated - bitwise : true, // if bitwise operators should not be allowed - boss : true, // if advanced usage of assignments should be allowed - browser : true, // if the standard browser globals should be predefined - camelcase : true, // if identifiers should be required in camel case - couch : true, // if CouchDB globals should be predefined - curly : true, // if curly braces around all blocks should be required - debug : true, // if debugger statements should be allowed - devel : true, // if logging globals should be predefined (console, - // alert, etc.) - dojo : true, // if Dojo Toolkit globals should be predefined - eqeqeq : true, // if === should be required - eqnull : true, // if == null comparisons should be tolerated - es5 : true, // if ES5 syntax should be allowed - esnext : true, // if es.next specific syntax should be allowed - evil : true, // if eval should be allowed - expr : true, // if ExpressionStatement should be allowed as Programs - forin : true, // if for in statements must filter - funcscope : true, // if only function scope should be used for scope tests - globalstrict: true, // if global "use strict"; should be allowed (also - // enables 'strict') - immed : true, // if immediate invocations must be wrapped in parens - iterator : true, // if the `__iterator__` property should be allowed - jquery : true, // if jQuery globals should be predefined - lastsemic : true, // if semicolons may be ommitted for the trailing - // statements inside of a one-line blocks. - latedef : true, // if the use before definition should not be tolerated - laxbreak : true, // if line breaks should not be checked - laxcomma : true, // if line breaks should not be checked around commas - loopfunc : true, // if functions should be allowed to be defined within - // loops - mootools : true, // if MooTools globals should be predefined - multistr : true, // allow multiline strings - newcap : true, // if constructor names must be capitalized - noarg : true, // if arguments.caller and arguments.callee should be - // disallowed - node : true, // if the Node.js environment globals should be - // predefined - noempty : true, // if empty blocks should be disallowed - nonew : true, // if using `new` for side-effects should be disallowed - nonstandard : true, // if non-standard (but widely adopted) globals should - // be predefined - nomen : true, // if names should be checked - onevar : true, // if only one var statement per function should be - // allowed - onecase : true, // if one case switch statements should be allowed - passfail : true, // if the scan should stop on first error - plusplus : true, // if increment/decrement should not be allowed - proto : true, // if the `__proto__` property should be allowed - prototypejs : true, // if Prototype and Scriptaculous globals should be - // predefined - regexdash : true, // if unescaped first/last dash (-) inside brackets - // should be tolerated - regexp : true, // if the . should not be allowed in regexp literals - rhino : true, // if the Rhino environment globals should be predefined - undef : true, // if variables should be declared before used - unused : true, // if variables should be always used - scripturl : true, // if script-targeted URLs should be tolerated - shadow : true, // if variable shadowing should be tolerated - smarttabs : true, // if smarttabs should be tolerated - // (http://www.emacswiki.org/emacs/SmartTabs) - strict : true, // require the "use strict"; pragma - sub : true, // if all forms of subscript notation are tolerated - supernew : true, // if `new function () { ... };` and `new Object;` - // should be tolerated - trailing : true, // if trailing whitespace rules apply - validthis : true, // if 'this' inside a non-constructor function is valid. - // This is a function scoped option only. - withstmt : true, // if with statements should be allowed - white : true, // if strict whitespace rules apply - worker : true, // if Web Worker script symbols should be allowed - wsh : true, // if the Windows Scripting Host environment globals - // should be predefined - yui : true // YUI variables should be predefined - }, - - // These are the JSHint options that can take any value - // (we use this object to detect invalid options) - valOptions = { - maxlen : false, - indent : false, - maxerr : false, - predef : false, - quotmark : false, //'single'|'double'|true - scope : false, - maxstatements: false, // {int} max statements per function - maxdepth : false, // {int} max nested block depth per function - maxparams : false, // {int} max params per function - maxcomplexity: false // {int} max cyclomatic complexity per function - }, - - // These are JSHint boolean options which are shared with JSLint - // where the definition in JSHint is opposite JSLint - invertedOptions = { - bitwise : true, - forin : true, - newcap : true, - nomen : true, - plusplus : true, - regexp : true, - undef : true, - white : true, - - // Inverted and renamed, use JSHint name here - eqeqeq : true, - onevar : true - }, - - // These are JSHint boolean options which are shared with JSLint - // where the name has been changed but the effect is unchanged - renamedOptions = { - eqeq : "eqeqeq", - vars : "onevar", - windows : "wsh" - }, - - - // browser contains a set of global names which are commonly provided by a - // web browser environment. - browser = { - ArrayBuffer : false, - ArrayBufferView : false, - Audio : false, - Blob : false, - addEventListener : false, - applicationCache : false, - atob : false, - blur : false, - btoa : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - DataView : false, - DOMParser : false, - defaultStatus : false, - document : false, - event : false, - FileReader : false, - Float32Array : false, - Float64Array : false, - FormData : false, - focus : false, - frames : false, - getComputedStyle : false, - HTMLElement : false, - HTMLAnchorElement : false, - HTMLBaseElement : false, - HTMLBlockquoteElement : false, - HTMLBodyElement : false, - HTMLBRElement : false, - HTMLButtonElement : false, - HTMLCanvasElement : false, - HTMLDirectoryElement : false, - HTMLDivElement : false, - HTMLDListElement : false, - HTMLFieldSetElement : false, - HTMLFontElement : false, - HTMLFormElement : false, - HTMLFrameElement : false, - HTMLFrameSetElement : false, - HTMLHeadElement : false, - HTMLHeadingElement : false, - HTMLHRElement : false, - HTMLHtmlElement : false, - HTMLIFrameElement : false, - HTMLImageElement : false, - HTMLInputElement : false, - HTMLIsIndexElement : false, - HTMLLabelElement : false, - HTMLLayerElement : false, - HTMLLegendElement : false, - HTMLLIElement : false, - HTMLLinkElement : false, - HTMLMapElement : false, - HTMLMenuElement : false, - HTMLMetaElement : false, - HTMLModElement : false, - HTMLObjectElement : false, - HTMLOListElement : false, - HTMLOptGroupElement : false, - HTMLOptionElement : false, - HTMLParagraphElement : false, - HTMLParamElement : false, - HTMLPreElement : false, - HTMLQuoteElement : false, - HTMLScriptElement : false, - HTMLSelectElement : false, - HTMLStyleElement : false, - HTMLTableCaptionElement : false, - HTMLTableCellElement : false, - HTMLTableColElement : false, - HTMLTableElement : false, - HTMLTableRowElement : false, - HTMLTableSectionElement : false, - HTMLTextAreaElement : false, - HTMLTitleElement : false, - HTMLUListElement : false, - HTMLVideoElement : false, - history : false, - Int16Array : false, - Int32Array : false, - Int8Array : false, - Image : false, - length : false, - localStorage : false, - location : false, - MessageChannel : false, - MessageEvent : false, - MessagePort : false, - moveBy : false, - moveTo : false, - MutationObserver : false, - name : false, - Node : false, - NodeFilter : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - openDatabase : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener : false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - sessionStorage : false, - setInterval : false, - setTimeout : false, - SharedWorker : false, - status : false, - top : false, - Uint16Array : false, - Uint32Array : false, - Uint8Array : false, - WebSocket : false, - window : false, - Worker : false, - XMLHttpRequest : false, - XMLSerializer : false, - XPathEvaluator : false, - XPathException : false, - XPathExpression : false, - XPathNamespace : false, - XPathNSResolver : false, - XPathResult : false - }, - - couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false, - provides : false - }, - - declared, // Globals that were declared using /*global ... */ syntax. - - devel = { - alert : false, - confirm : false, - console : false, - Debug : false, - opera : false, - prompt : false - }, - - dojo = { - dojo : false, - dijit : false, - dojox : false, - define : false, - "require" : false - }, - - funct, // The current function - - functionicity = [ - "closure", "exception", "global", "label", - "outer", "unused", "var" - ], - - functions, // All of the functions - - global, // The global scope - implied, // Implied globals - inblock, - indent, - jsonmode, - - jquery = { - "$" : false, - jQuery : false - }, - - lines, - lookahead, - member, - membersOnly, - - mootools = { - "$" : false, - "$$" : false, - Asset : false, - Browser : false, - Chain : false, - Class : false, - Color : false, - Cookie : false, - Core : false, - Document : false, - DomReady : false, - DOMEvent : false, - DOMReady : false, - Drag : false, - Element : false, - Elements : false, - Event : false, - Events : false, - Fx : false, - Group : false, - Hash : false, - HtmlTable : false, - Iframe : false, - IframeShim : false, - InputValidator : false, - instanceOf : false, - Keyboard : false, - Locale : false, - Mask : false, - MooTools : false, - Native : false, - Options : false, - OverText : false, - Request : false, - Scroller : false, - Slick : false, - Slider : false, - Sortables : false, - Spinner : false, - Swiff : false, - Tips : false, - Type : false, - typeOf : false, - URI : false, - Window : false - }, - - nexttoken, - - node = { - __filename : false, - __dirname : false, - Buffer : false, - console : false, - exports : true, // In Node it is ok to exports = module.exports = foo(); - GLOBAL : false, - global : false, - module : false, - process : false, - require : false, - setTimeout : false, - clearTimeout : false, - setInterval : false, - clearInterval : false - }, - - noreach, - option, - predefined, // Global variables defined by option - prereg, - prevtoken, - - prototypejs = { - "$" : false, - "$$" : false, - "$A" : false, - "$F" : false, - "$H" : false, - "$R" : false, - "$break" : false, - "$continue" : false, - "$w" : false, - Abstract : false, - Ajax : false, - Class : false, - Enumerable : false, - Element : false, - Event : false, - Field : false, - Form : false, - Hash : false, - Insertion : false, - ObjectRange : false, - PeriodicalExecuter: false, - Position : false, - Prototype : false, - Selector : false, - Template : false, - Toggle : false, - Try : false, - Autocompleter : false, - Builder : false, - Control : false, - Draggable : false, - Draggables : false, - Droppables : false, - Effect : false, - Sortable : false, - SortableObserver : false, - Sound : false, - Scriptaculous : false - }, - - quotmark, - - rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - importPackage: false, - "java" : false, - load : false, - loadClass : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false - }, - - scope, // The current scope - stack, - - // standard contains the global names that are provided by the - // ECMAScript standard. - standard = { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - "eval" : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - JSON : false, - Map : false, - Math : false, - NaN : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - Set : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false, - WeakMap : false - }, - - // widely adopted global names that are not part of ECMAScript standard - nonstandard = { - escape : false, - unescape : false - }, - - directive, - syntax = {}, - tab, - token, - unuseds, - urls, - useESNextSyntax, - warnings, - - worker = { - importScripts : true, - postMessage : true, - self : true - }, - - wsh = { - ActiveXObject : true, - Enumerator : true, - GetObject : true, - ScriptEngine : true, - ScriptEngineBuildVersion : true, - ScriptEngineMajorVersion : true, - ScriptEngineMinorVersion : true, - VBArray : true, - WSH : true, - WScript : true, - XDomainRequest : true - }, - - yui = { - YUI : false, - Y : false, - YUI_config : false - }; - // Regular expressions. Some of these are stupidly long. - var ax, cx, tx, nx, nxg, lx, ix, jx, ft; - (function () { - /*jshint maxlen:300 */ - - // unsafe comment or string - ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i; - - // unsafe characters that are silently deleted by one or more browsers - cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - - // token - tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/=(?!(\S*\/[gim]?))|\/(\*(jshint|jslint|members?|global)?|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/; - - // characters in strings that need escapement - nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - - // star slash - lx = /\*\//; - - // identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; - - // javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - - // catches /* falls through */ comments - ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/; - }()); - - function F() {} // Used by Object.create - - function is_own(object, name) { - // The object.hasOwnProperty method fails when the property under consideration - // is named 'hasOwnProperty'. So we have to use this more convoluted form. - return Object.prototype.hasOwnProperty.call(object, name); - } - - function checkOption(name, t) { - if (valOptions[name] === undefined && boolOptions[name] === undefined) { - warning("Bad option: '" + name + "'.", t); - } - } - - function isString(obj) { - return Object.prototype.toString.call(obj) === "[object String]"; - } - - // Provide critical ES5 functions to ES3. - - if (typeof Array.isArray !== "function") { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === "[object Array]"; - }; - } - - if (!Array.prototype.forEach) { - Array.prototype.forEach = function (fn, scope) { - var len = this.length; - - for (var i = 0; i < len; i++) { - fn.call(scope || this, this[i], i, this); - } - }; - } - - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { - if (this === null || this === undefined) { - throw new TypeError(); - } - - var t = new Object(this); - var len = t.length >>> 0; - - if (len === 0) { - return -1; - } - - var n = 0; - if (arguments.length > 0) { - n = Number(arguments[1]); - if (n != n) { // shortcut for verifying if it's NaN - n = 0; - } else if (n !== 0 && n != Infinity && n != -Infinity) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - } - - if (n >= len) { - return -1; - } - - var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); - for (; k < len; k++) { - if (k in t && t[k] === searchElement) { - return k; - } - } - - return -1; - }; - } - - if (typeof Object.create !== "function") { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== "function") { - Object.keys = function (o) { - var a = [], k; - for (k in o) { - if (is_own(o, k)) { - a.push(k); - } - } - return a; - }; - } - - // Non standard methods - - function isAlpha(str) { - return (str >= "a" && str <= "z\uffff") || - (str >= "A" && str <= "Z\uffff"); - } - - function isDigit(str) { - return (str >= "0" && str <= "9"); - } - - function isIdentifier(token, value) { - if (!token) - return false; - - if (!token.identifier || token.value !== value) - return false; - - return true; - } - - function supplant(str, data) { - return str.replace(/\{([^{}]*)\}/g, function (a, b) { - var r = data[b]; - return typeof r === "string" || typeof r === "number" ? r : a; - }); - } - - function combine(t, o) { - var n; - for (n in o) { - if (is_own(o, n) && !is_own(JSHINT.blacklist, n)) { - t[n] = o[n]; - } - } - } - - function updatePredefined() { - Object.keys(JSHINT.blacklist).forEach(function (key) { - delete predefined[key]; - }); - } - - function assume() { - if (option.couch) { - combine(predefined, couch); - } - - if (option.rhino) { - combine(predefined, rhino); - } - - if (option.prototypejs) { - combine(predefined, prototypejs); - } - - if (option.node) { - combine(predefined, node); - option.globalstrict = true; - } - - if (option.devel) { - combine(predefined, devel); - } - - if (option.dojo) { - combine(predefined, dojo); - } - - if (option.browser) { - combine(predefined, browser); - } - - if (option.nonstandard) { - combine(predefined, nonstandard); - } - - if (option.jquery) { - combine(predefined, jquery); - } - - if (option.mootools) { - combine(predefined, mootools); - } - - if (option.worker) { - combine(predefined, worker); - } - - if (option.wsh) { - combine(predefined, wsh); - } - - if (option.esnext) { - useESNextSyntax(); - } - - if (option.globalstrict && option.strict !== false) { - option.strict = true; - } - - if (option.yui) { - combine(predefined, yui); - } - } - - - // Produce an error warning. - function quit(message, line, chr) { - var percentage = Math.floor((line / lines.length) * 100); - - throw { - name: "JSHintError", - line: line, - character: chr, - message: message + " (" + percentage + "% scanned).", - raw: message - }; - } - - function isundef(scope, m, t, a) { - return JSHINT.undefs.push([scope, m, t, a]); - } - - function warning(m, t, a, b, c, d) { - var ch, l, w; - t = t || nexttoken; - if (t.id === "(end)") { // `~ - t = token; - } - l = t.line || 0; - ch = t.from || 0; - w = { - id: "(error)", - raw: m, - evidence: lines[l - 1] || "", - line: l, - character: ch, - scope: JSHINT.scope, - a: a, - b: b, - c: c, - d: d - }; - w.reason = supplant(m, w); - JSHINT.errors.push(w); - if (option.passfail) { - quit("Stopping. ", l, ch); - } - warnings += 1; - if (warnings >= option.maxerr) { - quit("Too many errors.", l, ch); - } - return w; - } - - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); - } - - function error(m, t, a, b, c, d) { - warning(m, t, a, b, c, d); - } - - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); - } - - // Tracking of "internal" scripts, like eval containing a static string - function addInternalSrc(elem, src) { - var i; - i = { - id: "(internal)", - elem: elem, - value: src - }; - JSHINT.internals.push(i); - return i; - } - - -// lexical analysis and token construction - - var lex = (function lex() { - var character, from, line, s; - -// Private lex methods - - function nextLine() { - var at, - match, - tw; // trailing whitespace check - - if (line >= lines.length) - return false; - - character = 1; - s = lines[line]; - line += 1; - - // If smarttabs option is used check for spaces followed by tabs only. - // Otherwise check for any occurence of mixed tabs and spaces. - // Tabs and one space followed by block comment is allowed. - if (option.smarttabs) { - // negative look-behind for "//" - match = s.match(/(\/\/)? \t/); - at = match && !match[1] ? 0 : -1; - } else { - at = s.search(/ \t|\t [^\*]/); - } - - if (at >= 0) - warningAt("Mixed spaces and tabs.", line, at + 1); - - s = s.replace(/\t/g, tab); - at = s.search(cx); - - if (at >= 0) - warningAt("Unsafe character.", line, at); - - if (option.maxlen && option.maxlen < s.length) - warningAt("Line too long.", line, s.length); - - // Check for trailing whitespaces - tw = option.trailing && s.match(/^(.*?)\s+$/); - if (tw && !/^\s+$/.test(s)) { - warningAt("Trailing whitespace.", line, tw[1].length + 1); - } - return true; - } - -// Produce a token object. The token inherits from a syntax symbol. - - function it(type, value) { - var i, t; - - function checkName(name) { - if (!option.proto && name === "__proto__") { - warningAt("The '{a}' property is deprecated.", line, from, name); - return; - } - - if (!option.iterator && name === "__iterator__") { - warningAt("'{a}' is only available in JavaScript 1.7.", line, from, name); - return; - } - - // Check for dangling underscores unless we're in Node - // environment and this identifier represents built-in - // Node globals with underscores. - - var hasDangling = /^(_+.*|.*_+)$/.test(name); - - if (option.nomen && hasDangling && name !== "_") { - if (option.node && token.id !== "." && /^(__dirname|__filename)$/.test(name)) - return; - - warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", name); - return; - } - - // Check for non-camelcase names. Names like MY_VAR and - // _myVar are okay though. - - if (option.camelcase) { - if (name.replace(/^_+/, "").indexOf("_") > -1 && !name.match(/^[A-Z0-9_]*$/)) { - warningAt("Identifier '{a}' is not in camel case.", line, from, value); - } - } - } - - if (type === "(color)" || type === "(range)") { - t = {type: type}; - } else if (type === "(punctuator)" || - (type === "(identifier)" && is_own(syntax, value))) { - t = syntax[value] || syntax["(error)"]; - } else { - t = syntax[type]; - } - - t = Object.create(t); - - if (type === "(string)" || type === "(range)") { - if (!option.scripturl && jx.test(value)) { - warningAt("Script URL.", line, from); - } - } - - if (type === "(identifier)") { - t.identifier = true; - checkName(value); - } - - t.value = value; - t.line = line; - t.character = character; - t.from = from; - i = t.id; - if (i !== "(endline)") { - prereg = i && - (("(,=:[!&|?{};".indexOf(i.charAt(i.length - 1)) >= 0) || - i === "return" || - i === "case"); - } - return t; - } - - // Public lex methods - return { - init: function (source) { - if (typeof source === "string") { - lines = source - .replace(/\r\n/g, "\n") - .replace(/\r/g, "\n") - .split("\n"); - } else { - lines = source; - } - - // If the first line is a shebang (#!), make it a blank and move on. - // Shebangs are used by Node scripts. - if (lines[0] && lines[0].substr(0, 2) === "#!") - lines[0] = ""; - - line = 0; - nextLine(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ""; - from = character; - if (s.charAt(0) !== begin) { - errorAt("Expected '{a}' and instead saw '{b}'.", - line, character, begin, s.charAt(0)); - } - for (;;) { - s = s.slice(1); - character += 1; - c = s.charAt(0); - switch (c) { - case "": - errorAt("Missing '{a}'.", line, character, c); - break; - case end: - s = s.slice(1); - character += 1; - return it("(range)", value); - case "\\": - warningAt("Unexpected '{a}'.", line, character, c); - } - value += c; - } - - }, - - - // token -- this is called by advance to get the next token - token: function () { - var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n; - - function match(x) { - var r = x.exec(s), r1; - - if (r) { - l = r[0].length; - r1 = r[1]; - c = r1.charAt(0); - s = s.substr(l); - from = character + l - r1.length; - character += l; - return r1; - } - } - - function string(x) { - var c, j, r = "", allowNewLine = false; - - if (jsonmode && x !== "\"") { - warningAt("Strings must use doublequote.", - line, character); - } - - if (option.quotmark) { - if (option.quotmark === "single" && x !== "'") { - warningAt("Strings must use singlequote.", - line, character); - } else if (option.quotmark === "double" && x !== "\"") { - warningAt("Strings must use doublequote.", - line, character); - } else if (option.quotmark === true) { - quotmark = quotmark || x; - if (quotmark !== x) { - warningAt("Mixed double and single quotes.", - line, character); - } - } - } - - function esc(n) { - var i = parseInt(s.substr(j + 1, n), 16); - j += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warningAt("Unnecessary escapement.", line, character); - } - character += n; - c = String.fromCharCode(i); - } - - j = 0; -unclosedString: for (;;) { - while (j >= s.length) { - j = 0; - - var cl = line, cf = from; - if (!nextLine()) { - errorAt("Unclosed string.", cl, cf); - break unclosedString; - } - - if (allowNewLine) { - allowNewLine = false; - } else { - warningAt("Unclosed string.", cl, cf); - } - } - - c = s.charAt(j); - if (c === x) { - character += 1; - s = s.substr(j + 1); - return it("(string)", r, x); - } - - if (c < " ") { - if (c === "\n" || c === "\r") { - break; - } - warningAt("Control character in string: {a}.", - line, character + j, s.slice(0, j)); - } else if (c === "\\") { - j += 1; - character += 1; - c = s.charAt(j); - n = s.charAt(j + 1); - switch (c) { - case "\\": - case "\"": - case "/": - break; - case "\'": - if (jsonmode) { - warningAt("Avoid \\'.", line, character); - } - break; - case "b": - c = "\b"; - break; - case "f": - c = "\f"; - break; - case "n": - c = "\n"; - break; - case "r": - c = "\r"; - break; - case "t": - c = "\t"; - break; - case "0": - c = "\0"; - // Octal literals fail in strict mode - // check if the number is between 00 and 07 - // where 'n' is the token next to 'c' - if (n >= 0 && n <= 7 && directive["use strict"]) { - warningAt( - "Octal literals are not allowed in strict mode.", - line, character); - } - break; - case "u": - esc(4); - break; - case "v": - if (jsonmode) { - warningAt("Avoid \\v.", line, character); - } - c = "\v"; - break; - case "x": - if (jsonmode) { - warningAt("Avoid \\x-.", line, character); - } - esc(2); - break; - case "": - // last character is escape character - // always allow new line if escaped, but show - // warning if option is not set - allowNewLine = true; - if (option.multistr) { - if (jsonmode) { - warningAt("Avoid EOL escapement.", line, character); - } - c = ""; - character -= 1; - break; - } - warningAt("Bad escapement of EOL. Use option multistr if needed.", - line, character); - break; - case "!": - if (s.charAt(j - 2) === "<") - break; - /*falls through*/ - default: - warningAt("Bad escapement.", line, character); - } - } - r += c; - character += 1; - j += 1; - } - } - - for (;;) { - if (!s) { - return it(nextLine() ? "(endline)" : "(end)", ""); - } - - t = match(tx); - - if (!t) { - t = ""; - c = ""; - while (s && s < "!") { - s = s.substr(1); - } - if (s) { - errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1)); - s = ""; - } - } else { - - // identifier - - if (isAlpha(c) || c === "_" || c === "$") { - return it("(identifier)", t); - } - - // number - - if (isDigit(c)) { - if (!isFinite(Number(t))) { - warningAt("Bad number '{a}'.", - line, character, t); - } - if (isAlpha(s.substr(0, 1))) { - warningAt("Missing space after '{a}'.", - line, character, t); - } - if (c === "0") { - d = t.substr(1, 1); - if (isDigit(d)) { - if (token.id !== ".") { - warningAt("Don't use extra leading zeros '{a}'.", - line, character, t); - } - } else if (jsonmode && (d === "x" || d === "X")) { - warningAt("Avoid 0x-. '{a}'.", - line, character, t); - } - } - if (t.substr(t.length - 1) === ".") { - warningAt( -"A trailing decimal point can be confused with a dot '{a}'.", line, character, t); - } - return it("(number)", t); - } - switch (t) { - - // string - - case "\"": - case "'": - return string(t); - - // // comment - - case "//": - s = ""; - token.comment = true; - break; - - // /* comment - - case "/*": - for (;;) { - i = s.search(lx); - if (i >= 0) { - break; - } - if (!nextLine()) { - errorAt("Unclosed comment.", line, character); - } - } - s = s.substr(i + 2); - token.comment = true; - break; - - // /*members /*jshint /*global - - case "/*members": - case "/*member": - case "/*jshint": - case "/*jslint": - case "/*global": - case "*/": - return { - value: t, - type: "special", - line: line, - character: character, - from: from - }; - - case "": - break; - // / - case "/": - if (s.charAt(0) === "=") { - errorAt("A regular expression literal can be confused with '/='.", - line, from); - } - - if (prereg) { - depth = 0; - captures = 0; - l = 0; - for (;;) { - b = true; - c = s.charAt(l); - l += 1; - switch (c) { - case "": - errorAt("Unclosed regular expression.", line, from); - return quit("Stopping.", line, from); - case "/": - if (depth > 0) { - warningAt("{a} unterminated regular expression " + - "group(s).", line, from + l, depth); - } - c = s.substr(0, l - 1); - q = { - g: true, - i: true, - m: true - }; - while (q[s.charAt(l)] === true) { - q[s.charAt(l)] = false; - l += 1; - } - character += l; - s = s.substr(l); - q = s.charAt(0); - if (q === "/" || q === "*") { - errorAt("Confusing regular expression.", - line, from); - } - return it("(regexp)", c); - case "\\": - c = s.charAt(l); - if (c < " ") { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === "<") { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - break; - case "(": - depth += 1; - b = false; - if (s.charAt(l) === "?") { - l += 1; - switch (s.charAt(l)) { - case ":": - case "=": - case "!": - l += 1; - break; - default: - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, ":", s.charAt(l)); - } - } else { - captures += 1; - } - break; - case "|": - b = false; - break; - case ")": - if (depth === 0) { - warningAt("Unescaped '{a}'.", - line, from + l, ")"); - } else { - depth -= 1; - } - break; - case " ": - q = 1; - while (s.charAt(l) === " ") { - l += 1; - q += 1; - } - if (q > 1) { - warningAt( -"Spaces are hard to count. Use {{a}}.", line, from + l, q); - } - break; - case "[": - c = s.charAt(l); - if (c === "^") { - l += 1; - if (s.charAt(l) === "]") { - errorAt("Unescaped '{a}'.", - line, from + l, "^"); - } - } - if (c === "]") { - warningAt("Empty class.", line, - from + l - 1); - } - isLiteral = false; - isInRange = false; -klass: do { - c = s.charAt(l); - l += 1; - switch (c) { - case "[": - case "^": - warningAt("Unescaped '{a}'.", - line, from + l, c); - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case "-": - if (isLiteral && !isInRange) { - isLiteral = false; - isInRange = true; - } else if (isInRange) { - isInRange = false; - } else if (s.charAt(l) === "]") { - isInRange = true; - } else { - if (option.regexdash !== (l === 2 || (l === 3 && - s.charAt(1) === "^"))) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, "-"); - } - isLiteral = true; - } - break; - case "]": - if (isInRange && !option.regexdash) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, "-"); - } - break klass; - case "\\": - c = s.charAt(l); - if (c < " ") { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === "<") { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - - // \w, \s and \d are never part of a character range - if (/[wsd]/i.test(c)) { - if (isInRange) { - warningAt("Unescaped '{a}'.", - line, from + l, "-"); - isInRange = false; - } - isLiteral = false; - } else if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case "/": - warningAt("Unescaped '{a}'.", - line, from + l - 1, "/"); - - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case "<": - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - default: - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - } - } while (c); - break; - case ".": - if (option.regexp) { - warningAt("Insecure '{a}'.", line, - from + l, c); - } - break; - case "]": - case "?": - case "{": - case "}": - case "+": - case "*": - warningAt("Unescaped '{a}'.", line, - from + l, c); - } - if (b) { - switch (s.charAt(l)) { - case "?": - case "+": - case "*": - l += 1; - if (s.charAt(l) === "?") { - l += 1; - } - break; - case "{": - l += 1; - c = s.charAt(l); - if (c < "0" || c > "9") { - warningAt( -"Expected a number and instead saw '{a}'.", line, from + l, c); - break; // No reason to continue checking numbers. - } - l += 1; - low = +c; - for (;;) { - c = s.charAt(l); - if (c < "0" || c > "9") { - break; - } - l += 1; - low = +c + (low * 10); - } - high = low; - if (c === ",") { - l += 1; - high = Infinity; - c = s.charAt(l); - if (c >= "0" && c <= "9") { - l += 1; - high = +c; - for (;;) { - c = s.charAt(l); - if (c < "0" || c > "9") { - break; - } - l += 1; - high = +c + (high * 10); - } - } - } - if (s.charAt(l) !== "}") { - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, "}", c); - } else { - l += 1; - } - if (s.charAt(l) === "?") { - l += 1; - } - if (low > high) { - warningAt( -"'{a}' should not be greater than '{b}'.", line, from + l, low, high); - } - } - } - } - c = s.substr(0, l - 1); - character += l; - s = s.substr(l); - return it("(regexp)", c); - } - return it("(punctuator)", t); - - // punctuator - - case "#": - return it("(punctuator)", t); - default: - return it("(punctuator)", t); - } - } - } - } - }; - }()); - - - function addlabel(t, type, token) { - if (t === "hasOwnProperty") { - warning("'hasOwnProperty' is a really bad name."); - } - - // Define t in the current function in the current scope. - if (type === "exception") { - if (is_own(funct["(context)"], t)) { - if (funct[t] !== true && !option.node) { - warning("Value of '{a}' may be overwritten in IE.", nexttoken, t); - } - } - } - - if (is_own(funct, t) && !funct["(global)"]) { - if (funct[t] === true) { - if (option.latedef) - warning("'{a}' was used before it was defined.", nexttoken, t); - } else { - if (!option.shadow && type !== "exception") { - warning("'{a}' is already defined.", nexttoken, t); - } - } - } - - funct[t] = type; - - if (token) { - funct["(tokens)"][t] = token; - } - - if (funct["(global)"]) { - global[t] = funct; - if (is_own(implied, t)) { - if (option.latedef) - warning("'{a}' was used before it was defined.", nexttoken, t); - delete implied[t]; - } - } else { - scope[t] = funct; - } - } - - - function doOption() { - var nt = nexttoken; - var o = nt.value; - var quotmarkValue = option.quotmark; - var predef = {}; - var b, obj, filter, t, tn, v, minus; - - switch (o) { - case "*/": - error("Unbegun comment."); - break; - case "/*members": - case "/*member": - o = "/*members"; - if (!membersOnly) { - membersOnly = {}; - } - obj = membersOnly; - option.quotmark = false; - break; - case "/*jshint": - case "/*jslint": - obj = option; - filter = boolOptions; - break; - case "/*global": - obj = predef; - break; - default: - error("What?"); - } - - t = lex.token(); -loop: for (;;) { - minus = false; - for (;;) { - if (t.type === "special" && t.value === "*/") { - break loop; - } - if (t.id !== "(endline)" && t.id !== ",") { - break; - } - t = lex.token(); - } - - if (o === "/*global" && t.value === "-") { - minus = true; - t = lex.token(); - } - - if (t.type !== "(string)" && t.type !== "(identifier)" && o !== "/*members") { - error("Bad option.", t); - } - - v = lex.token(); - if (v.id === ":") { - v = lex.token(); - - if (obj === membersOnly) { - error("Expected '{a}' and instead saw '{b}'.", t, "*/", ":"); - } - - if (o === "/*jshint") { - checkOption(t.value, t); - } - - var numericVals = [ - "maxstatements", - "maxparams", - "maxdepth", - "maxcomplexity", - "maxerr", - "maxlen", - "indent" - ]; - - if (numericVals.indexOf(t.value) > -1 && (o === "/*jshint" || o === "/*jslint")) { - b = +v.value; - - if (typeof b !== "number" || !isFinite(b) || b <= 0 || Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", v, v.value); - } - - if (t.value === "indent") - obj.white = true; - - obj[t.value] = b; - } else if (t.value === "validthis") { - if (funct["(global)"]) { - error("Option 'validthis' can't be used in a global scope."); - } else { - if (v.value === "true" || v.value === "false") - obj[t.value] = v.value === "true"; - else - error("Bad option value.", v); - } - } else if (t.value === "quotmark" && (o === "/*jshint")) { - switch (v.value) { - case "true": - obj.quotmark = true; - break; - case "false": - obj.quotmark = false; - break; - case "double": - case "single": - obj.quotmark = v.value; - break; - default: - error("Bad option value.", v); - } - } else if (v.value === "true" || v.value === "false") { - if (o === "/*jslint") { - tn = renamedOptions[t.value] || t.value; - obj[tn] = v.value === "true"; - if (invertedOptions[tn] !== undefined) { - obj[tn] = !obj[tn]; - } - } else { - obj[t.value] = v.value === "true"; - } - - if (t.value === "newcap") - obj["(explicitNewcap)"] = true; - } else { - error("Bad option value.", v); - } - t = lex.token(); - } else { - if (o === "/*jshint" || o === "/*jslint") { - error("Missing option value.", t); - } - - obj[t.value] = false; - - if (o === "/*global" && minus === true) { - JSHINT.blacklist[t.value] = t.value; - updatePredefined(); - } - - t = v; - } - } - - if (o === "/*members") { - option.quotmark = quotmarkValue; - } - - combine(predefined, predef); - - for (var key in predef) { - if (is_own(predef, key)) { - declared[key] = nt; - } - } - - if (filter) { - assume(); - } - } - - -// We need a peek function. If it has an argument, it peeks that much farther -// ahead. It is used to distinguish -// for ( var i in ... -// from -// for ( var i = ... - - function peek(p) { - var i = p || 0, j = 0, t; - - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; - } - return t; - } - - - -// Produce the next token. It looks for programming errors. - - function advance(id, t) { - switch (token.id) { - case "(number)": - if (nexttoken.id === ".") { - warning("A dot following a number can be confused with a decimal point.", token); - } - break; - case "-": - if (nexttoken.id === "-" || nexttoken.id === "--") { - warning("Confusing minusses."); - } - break; - case "+": - if (nexttoken.id === "+" || nexttoken.id === "++") { - warning("Confusing plusses."); - } - break; - } - - if (token.type === "(string)" || token.identifier) { - anonname = token.value; - } - - if (id && nexttoken.id !== id) { - if (t) { - if (nexttoken.id === "(end)") { - warning("Unmatched '{a}'.", t, t.id); - } else { - warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - nexttoken, id, t.id, t.line, nexttoken.value); - } - } else if (nexttoken.type !== "(identifier)" || - nexttoken.value !== id) { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, id, nexttoken.value); - } - } - - prevtoken = token; - token = nexttoken; - for (;;) { - nexttoken = lookahead.shift() || lex.token(); - if (nexttoken.id === "(end)" || nexttoken.id === "(error)") { - return; - } - if (nexttoken.type === "special") { - doOption(); - } else { - if (nexttoken.id !== "(endline)") { - break; - } - } - } - } - - -// This is the heart of JSHINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. - -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power - -// They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - var left, isArray = false, isObject = false; - - if (nexttoken.id === "(end)") - error("Unexpected early end of program.", token); - - advance(); - if (initial) { - anonname = "anonymous"; - funct["(verb)"] = token.value; - } - if (initial === true && token.fud) { - left = token.fud(); - } else { - if (token.nud) { - left = token.nud(); - } else { - if (nexttoken.type === "(number)" && token.id === ".") { - warning("A leading decimal point can be confused with a dot: '.{a}'.", - token, nexttoken.value); - advance(); - return token; - } else { - error("Expected an identifier and instead saw '{a}'.", - token, token.id); - } - } - while (rbp < nexttoken.lbp) { - isArray = token.value === "Array"; - isObject = token.value === "Object"; - - // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() - // Line breaks in IfStatement heads exist to satisfy the checkJSHint - // "Line too long." error. - if (left && (left.value || (left.first && left.first.value))) { - // If the left.value is not "new", or the left.first.value is a "." - // then safely assume that this is not "new Array()" and possibly - // not "new Object()"... - if (left.value !== "new" || - (left.first && left.first.value && left.first.value === ".")) { - isArray = false; - // ...In the case of Object, if the left.value and token.value - // are not equal, then safely assume that this not "new Object()" - if (left.value !== token.value) { - isObject = false; - } - } - } - - advance(); - if (isArray && token.id === "(" && nexttoken.id === ")") - warning("Use the array literal notation [].", token); - if (isObject && token.id === "(" && nexttoken.id === ")") - warning("Use the object literal notation {}.", token); - if (token.led) { - left = token.led(left); - } else { - error("Expected an operator and instead saw '{a}'.", - token, token.id); - } - } - } - return left; - } - - -// Functions for conformance of style. - - function adjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white) { - if (left.character !== right.from && left.line === right.line) { - left.from += (left.character - left.from); - warning("Unexpected space after '{a}'.", left, left.value); - } - } - } - - function nobreak(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && (left.character !== right.from || left.line !== right.line)) { - warning("Unexpected space before '{a}'.", right, right.value); - } - } - - function nospace(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && !left.comment) { - if (left.line === right.line) { - adjacent(left, right); - } - } - } - - function nonadjacent(left, right) { - if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.value === ";" && right.value === ";") { - return; - } - if (left.line === right.line && left.character === right.from) { - left.from += (left.character - left.from); - warning("Missing space after '{a}'.", - left, left.value); - } - } - } - - function nobreaknonadjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (!option.laxbreak && left.line !== right.line) { - warning("Bad line breaking before '{a}'.", right, right.id); - } else if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.character === right.from) { - left.from += (left.character - left.from); - warning("Missing space after '{a}'.", - left, left.value); - } - } - } - - function indentation(bias) { - var i; - if (option.white && nexttoken.id !== "(end)") { - i = indent + (bias || 0); - if (nexttoken.from !== i) { - warning( -"Expected '{a}' to have an indentation at {b} instead at {c}.", - nexttoken, nexttoken.value, i, nexttoken.from); - } - } - } - - function nolinebreak(t) { - t = t || token; - if (t.line !== nexttoken.line) { - warning("Line breaking error '{a}'.", t, t.value); - } - } - - - function comma() { - if (token.line !== nexttoken.line) { - if (!option.laxcomma) { - if (comma.first) { - warning("Comma warnings can be turned off with 'laxcomma'"); - comma.first = false; - } - warning("Bad line breaking before '{a}'.", token, nexttoken.id); - } - } else if (!token.comment && token.character !== nexttoken.from && option.white) { - token.from += (token.character - token.from); - warning("Unexpected space after '{a}'.", token, token.value); - } - advance(","); - nonadjacent(token, nexttoken); - } - - -// Functional constructors for making the symbols that will be inherited by -// tokens. - - function symbol(s, p) { - var x = syntax[s]; - if (!x || typeof x !== "object") { - syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } - - - function delim(s) { - return symbol(s, 0); - } - - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - - function blockstmt(s, f) { - var x = stmt(s, f); - x.block = true; - return x; - } - - - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { - x.identifier = x.reserved = true; - } - return x; - } - - - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); - x.nud = (typeof f === "function") ? f : function () { - this.right = expression(150); - this.arity = "unary"; - if (this.id === "++" || this.id === "--") { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!this.right.identifier || this.right.reserved) && - this.right.id !== "." && this.right.id !== "[") { - warning("Bad operand.", this); - } - } - return this; - }; - return x; - } - - - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; - } - - - function reserve(s, f) { - var x = type(s, f); - x.identifier = x.reserved = true; - return x; - } - - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === "function") { - v(this); - } - return this; - }); - } - - - function infix(s, f, p, w) { - var x = symbol(s, p); - reserveName(x); - x.led = function (left) { - if (!w) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - } - if (s === "in" && left.id === "!") { - warning("Confusing use of '{a}'.", left, "!"); - } - if (typeof f === "function") { - return f(left, this); - } else { - this.left = left; - this.right = expression(p); - return this; - } - }; - return x; - } - - - function relation(s, f) { - var x = symbol(s, 100); - x.led = function (left) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - var right = expression(100); - - if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { - warning("Use the isNaN function to compare with NaN.", this); - } else if (f) { - f.apply(this, [left, right]); - } - if (left.id === "!") { - warning("Confusing use of '{a}'.", left, "!"); - } - if (right.id === "!") { - warning("Confusing use of '{a}'.", right, "!"); - } - this.left = left; - this.right = right; - return this; - }; - return x; - } - - - function isPoorRelation(node) { - return node && - ((node.type === "(number)" && +node.value === 0) || - (node.type === "(string)" && node.value === "") || - (node.type === "null" && !option.eqnull) || - node.type === "true" || - node.type === "false" || - node.type === "undefined"); - } - - - function assignop(s) { - symbol(s, 20).exps = true; - - return infix(s, function (left, that) { - that.left = left; - - if (predefined[left.value] === false && - scope[left.value]["(global)"] === true) { - warning("Read only.", left); - } else if (left["function"]) { - warning("'{a}' is a function.", left, left.value); - } - - if (left) { - if (option.esnext && funct[left.value] === "const") { - warning("Attempting to override '{a}' which is a constant", left, left.value); - } - - if (left.id === "." || left.id === "[") { - if (!left.left || left.left.value === "arguments") { - warning("Bad assignment.", that); - } - that.right = expression(19); - return that; - } else if (left.identifier && !left.reserved) { - if (funct[left.value] === "exception") { - warning("Do not assign to the exception parameter.", left); - } - that.right = expression(19); - return that; - } - - if (left === syntax["function"]) { - warning( -"Expected an identifier in an assignment and instead saw a function invocation.", - token); - } - } - - error("Bad assignment.", that); - }, 20); - } - - - function bitwise(s, f, p) { - var x = symbol(s, p); - reserveName(x); - x.led = (typeof f === "function") ? f : function (left) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", this, this.id); - } - this.left = left; - this.right = expression(p); - return this; - }; - return x; - } - - - function bitwiseassignop(s) { - symbol(s, 20).exps = true; - return infix(s, function (left, that) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", that, that.id); - } - nonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - if (left) { - if (left.id === "." || left.id === "[" || - (left.identifier && !left.reserved)) { - expression(19); - return that; - } - if (left === syntax["function"]) { - warning( -"Expected an identifier in an assignment, and instead saw a function invocation.", - token); - } - return that; - } - error("Bad assignment.", that); - }, 20); - } - - - function suffix(s) { - var x = symbol(s, 150); - x.led = function (left) { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!left.identifier || left.reserved) && - left.id !== "." && left.id !== "[") { - warning("Bad operand.", this); - } - this.left = left; - return this; - }; - return x; - } - - - // fnparam means that this identifier is being defined as a function - // argument (see identifier()) - function optionalidentifier(fnparam) { - if (nexttoken.identifier) { - advance(); - if (token.reserved && !option.es5) { - // `undefined` as a function param is a common pattern to protect - // against the case when somebody does `undefined = true` and - // help with minification. More info: https://gist.github.com/315916 - if (!fnparam || token.value !== "undefined") { - warning("Expected an identifier and instead saw '{a}' (a reserved word).", - token, token.id); - } - } - return token.value; - } - } - - // fnparam means that this identifier is being defined as a function - // argument - function identifier(fnparam) { - var i = optionalidentifier(fnparam); - if (i) { - return i; - } - if (token.id === "function" && nexttoken.id === "(") { - warning("Missing name in function declaration."); - } else { - error("Expected an identifier and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - } - - - function reachable(s) { - var i = 0, t; - if (nexttoken.id !== ";" || noreach) { - return; - } - for (;;) { - t = peek(i); - if (t.reach) { - return; - } - if (t.id !== "(endline)") { - if (t.id === "function") { - if (!option.latedef) { - break; - } - warning( -"Inner functions should be listed at the top of the outer function.", t); - break; - } - warning("Unreachable '{a}' after '{b}'.", t, t.value, s); - break; - } - i += 1; - } - } - - - function statement(noindent) { - var i = indent, r, s = scope, t = nexttoken; - - if (t.id === ";") { - advance(";"); - return; - } - - // Is this a labelled statement? - - if (t.identifier && !t.reserved && peek().id === ":") { - advance(); - advance(":"); - scope = Object.create(s); - addlabel(t.value, "label"); - - if (!nexttoken.labelled && nexttoken.value !== "{") { - warning("Label '{a}' on {b} statement.", nexttoken, t.value, nexttoken.value); - } - - if (jx.test(t.value + ":")) { - warning("Label '{a}' looks like a javascript url.", t, t.value); - } - - nexttoken.label = t.value; - t = nexttoken; - } - - // Is it a lonely block? - - if (t.id === "{") { - block(true, true); - return; - } - - // Parse the statement. - - if (!noindent) { - indentation(); - } - r = expression(0, true); - - // Look for the final semicolon. - - if (!t.block) { - if (!option.expr && (!r || !r.exps)) { - warning("Expected an assignment or function call and instead saw an expression.", - token); - } else if (option.nonew && r.id === "(" && r.left.id === "new") { - warning("Do not use 'new' for side effects.", t); - } - - if (nexttoken.id === ",") { - return comma(); - } - - if (nexttoken.id !== ";") { - if (!option.asi) { - // If this is the last statement in a block that ends on - // the same line *and* option lastsemic is on, ignore the warning. - // Otherwise, complain about missing semicolon. - if (!option.lastsemic || nexttoken.id !== "}" || - nexttoken.line !== token.line) { - warningAt("Missing semicolon.", token.line, token.character); - } - } - } else { - adjacent(token, nexttoken); - advance(";"); - nonadjacent(token, nexttoken); - } - } - -// Restore the indentation. - - indent = i; - scope = s; - return r; - } - - - function statements(startLine) { - var a = [], p; - - while (!nexttoken.reach && nexttoken.id !== "(end)") { - if (nexttoken.id === ";") { - p = peek(); - if (!p || p.id !== "(") { - warning("Unnecessary semicolon."); - } - advance(";"); - } else { - a.push(statement(startLine === nexttoken.line)); - } - } - return a; - } - - - /* - * read all directives - * recognizes a simple form of asi, but always - * warns, if it is used - */ - function directives() { - var i, p, pn; - - for (;;) { - if (nexttoken.id === "(string)") { - p = peek(0); - if (p.id === "(endline)") { - i = 1; - do { - pn = peek(i); - i = i + 1; - } while (pn.id === "(endline)"); - - if (pn.id !== ";") { - if (pn.id !== "(string)" && pn.id !== "(number)" && - pn.id !== "(regexp)" && pn.identifier !== true && - pn.id !== "}") { - break; - } - warning("Missing semicolon.", nexttoken); - } else { - p = pn; - } - } else if (p.id === "}") { - // directive with no other statements, warn about missing semicolon - warning("Missing semicolon.", p); - } else if (p.id !== ";") { - break; - } - - indentation(); - advance(); - if (directive[token.value]) { - warning("Unnecessary directive \"{a}\".", token, token.value); - } - - if (token.value === "use strict") { - if (!option["(explicitNewcap)"]) - option.newcap = true; - option.undef = true; - } - - // there's no directive negation, so always set to true - directive[token.value] = true; - - if (p.id === ";") { - advance(";"); - } - continue; - } - break; - } - } - - - /* - * Parses a single block. A block is a sequence of statements wrapped in - * braces. - * - * ordinary - true for everything but function bodies and try blocks. - * stmt - true if block can be a single statement (e.g. in if/for/while). - * isfunc - true if block is a function body - */ - function block(ordinary, stmt, isfunc) { - var a, - b = inblock, - old_indent = indent, - m, - s = scope, - t, - line, - d; - - inblock = ordinary; - - if (!ordinary || !option.funcscope) - scope = Object.create(scope); - - nonadjacent(token, nexttoken); - t = nexttoken; - - var metrics = funct["(metrics)"]; - metrics.nestedBlockDepth += 1; - metrics.verifyMaxNestedBlockDepthPerFunction(); - - if (nexttoken.id === "{") { - advance("{"); - line = token.line; - if (nexttoken.id !== "}") { - indent += option.indent; - while (!ordinary && nexttoken.from > indent) { - indent += option.indent; - } - - if (isfunc) { - m = {}; - for (d in directive) { - if (is_own(directive, d)) { - m[d] = directive[d]; - } - } - directives(); - - if (option.strict && funct["(context)"]["(global)"]) { - if (!m["use strict"] && !directive["use strict"]) { - warning("Missing \"use strict\" statement."); - } - } - } - - a = statements(line); - - metrics.statementCount += a.length; - - if (isfunc) { - directive = m; - } - - indent -= option.indent; - if (line !== nexttoken.line) { - indentation(); - } - } else if (line !== nexttoken.line) { - indentation(); - } - advance("}", t); - indent = old_indent; - } else if (!ordinary) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, "{", nexttoken.value); - } else { - if (!stmt || option.curly) - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, "{", nexttoken.value); - - noreach = true; - indent += option.indent; - // test indentation only if statement is in new line - a = [statement(nexttoken.line === token.line)]; - indent -= option.indent; - noreach = false; - } - funct["(verb)"] = null; - if (!ordinary || !option.funcscope) scope = s; - inblock = b; - if (ordinary && option.noempty && (!a || a.length === 0)) { - warning("Empty block."); - } - metrics.nestedBlockDepth -= 1; - return a; - } - - - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== "boolean") { - warning("Unexpected /*member '{a}'.", token, m); - } - if (typeof member[m] === "number") { - member[m] += 1; - } else { - member[m] = 1; - } - } - - - function note_implied(token) { - var name = token.value, line = token.line, a = implied[name]; - if (typeof a === "function") { - a = false; - } - - if (!a) { - a = [line]; - implied[name] = a; - } else if (a[a.length - 1] !== line) { - a.push(line); - } - } - - - // Build the syntax table by declaring the syntactic elements of the language. - - type("(number)", function () { - return this; - }); - - type("(string)", function () { - return this; - }); - - syntax["(identifier)"] = { - type: "(identifier)", - lbp: 0, - identifier: true, - nud: function () { - var v = this.value, - s = scope[v], - f; - - if (typeof s === "function") { - // Protection against accidental inheritance. - s = undefined; - } else if (typeof s === "boolean") { - f = funct; - funct = functions[0]; - addlabel(v, "var"); - s = funct; - funct = f; - } - - // The name is in scope and defined in the current function. - if (funct === s) { - // Change 'unused' to 'var', and reject labels. - switch (funct[v]) { - case "unused": - funct[v] = "var"; - break; - case "unction": - funct[v] = "function"; - this["function"] = true; - break; - case "function": - this["function"] = true; - break; - case "label": - warning("'{a}' is a statement label.", token, v); - break; - } - } else if (funct["(global)"]) { - // The name is not defined in the function. If we are in the global - // scope, then we have an undefined variable. - // - // Operators typeof and delete do not raise runtime errors even if - // the base object of a reference is null so no need to display warning - // if we're inside of typeof or delete. - - if (option.undef && typeof predefined[v] !== "boolean") { - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === "typeof" || anonname === "delete") || - (nexttoken && (nexttoken.value === "." || nexttoken.value === "["))) { - - isundef(funct, "'{a}' is not defined.", token, v); - } - } - - note_implied(token); - } else { - // If the name is already defined in the current - // function, but not as outer, then there is a scope error. - - switch (funct[v]) { - case "closure": - case "function": - case "var": - case "unused": - warning("'{a}' used out of scope.", token, v); - break; - case "label": - warning("'{a}' is a statement label.", token, v); - break; - case "outer": - case "global": - break; - default: - // If the name is defined in an outer function, make an outer entry, - // and if it was unused, make it var. - if (s === true) { - funct[v] = true; - } else if (s === null) { - warning("'{a}' is not allowed.", token, v); - note_implied(token); - } else if (typeof s !== "object") { - // Operators typeof and delete do not raise runtime errors even - // if the base object of a reference is null so no need to - // display warning if we're inside of typeof or delete. - if (option.undef) { - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === "typeof" || anonname === "delete") || - (nexttoken && - (nexttoken.value === "." || nexttoken.value === "["))) { - - isundef(funct, "'{a}' is not defined.", token, v); - } - } - funct[v] = true; - note_implied(token); - } else { - switch (s[v]) { - case "function": - case "unction": - this["function"] = true; - s[v] = "closure"; - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "var": - case "unused": - s[v] = "closure"; - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "closure": - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "label": - warning("'{a}' is a statement label.", token, v); - } - } - } - } - return this; - }, - led: function () { - error("Expected an operator and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - }; - - type("(regexp)", function () { - return this; - }); - - -// ECMAScript parser - - delim("(endline)"); - delim("(begin)"); - delim("(end)").reach = true; - delim(""); - delim("(error)").reach = true; - delim("}").reach = true; - delim(")"); - delim("]"); - delim("\"").reach = true; - delim("'").reach = true; - delim(";"); - delim(":").reach = true; - delim(","); - delim("#"); - delim("@"); - reserve("else"); - reserve("case").reach = true; - reserve("catch"); - reserve("default").reach = true; - reserve("finally"); - reservevar("arguments", function (x) { - if (directive["use strict"] && funct["(global)"]) { - warning("Strict violation.", x); - } - }); - reservevar("eval"); - reservevar("false"); - reservevar("Infinity"); - reservevar("null"); - reservevar("this", function (x) { - if (directive["use strict"] && !option.validthis && ((funct["(statement)"] && - funct["(name)"].charAt(0) > "Z") || funct["(global)"])) { - warning("Possible strict violation.", x); - } - }); - reservevar("true"); - reservevar("undefined"); - assignop("=", "assign", 20); - assignop("+=", "assignadd", 20); - assignop("-=", "assignsub", 20); - assignop("*=", "assignmult", 20); - assignop("/=", "assigndiv", 20).nud = function () { - error("A regular expression literal can be confused with '/='."); - }; - assignop("%=", "assignmod", 20); - bitwiseassignop("&=", "assignbitand", 20); - bitwiseassignop("|=", "assignbitor", 20); - bitwiseassignop("^=", "assignbitxor", 20); - bitwiseassignop("<<=", "assignshiftleft", 20); - bitwiseassignop(">>=", "assignshiftright", 20); - bitwiseassignop(">>>=", "assignshiftrightunsigned", 20); - infix("?", function (left, that) { - that.left = left; - that.right = expression(10); - advance(":"); - that["else"] = expression(10); - return that; - }, 30); - - infix("||", "or", 40); - infix("&&", "and", 50); - bitwise("|", "bitor", 70); - bitwise("^", "bitxor", 80); - bitwise("&", "bitand", 90); - relation("==", function (left, right) { - var eqnull = option.eqnull && (left.value === "null" || right.value === "null"); - - if (!eqnull && option.eqeqeq) - warning("Expected '{a}' and instead saw '{b}'.", this, "===", "=="); - else if (isPoorRelation(left)) - warning("Use '{a}' to compare with '{b}'.", this, "===", left.value); - else if (isPoorRelation(right)) - warning("Use '{a}' to compare with '{b}'.", this, "===", right.value); - - return this; - }); - relation("==="); - relation("!=", function (left, right) { - var eqnull = option.eqnull && - (left.value === "null" || right.value === "null"); - - if (!eqnull && option.eqeqeq) { - warning("Expected '{a}' and instead saw '{b}'.", - this, "!==", "!="); - } else if (isPoorRelation(left)) { - warning("Use '{a}' to compare with '{b}'.", - this, "!==", left.value); - } else if (isPoorRelation(right)) { - warning("Use '{a}' to compare with '{b}'.", - this, "!==", right.value); - } - return this; - }); - relation("!=="); - relation("<"); - relation(">"); - relation("<="); - relation(">="); - bitwise("<<", "shiftleft", 120); - bitwise(">>", "shiftright", 120); - bitwise(">>>", "shiftrightunsigned", 120); - infix("in", "in", 120); - infix("instanceof", "instanceof", 120); - infix("+", function (left, that) { - var right = expression(130); - if (left && right && left.id === "(string)" && right.id === "(string)") { - left.value += right.value; - left.character = right.character; - if (!option.scripturl && jx.test(left.value)) { - warning("JavaScript URL.", left); - } - return left; - } - that.left = left; - that.right = right; - return that; - }, 130); - prefix("+", "num"); - prefix("+++", function () { - warning("Confusing pluses."); - this.right = expression(150); - this.arity = "unary"; - return this; - }); - infix("+++", function (left) { - warning("Confusing pluses."); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("-", "sub", 130); - prefix("-", "neg"); - prefix("---", function () { - warning("Confusing minuses."); - this.right = expression(150); - this.arity = "unary"; - return this; - }); - infix("---", function (left) { - warning("Confusing minuses."); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("*", "mult", 140); - infix("/", "div", 140); - infix("%", "mod", 140); - - suffix("++", "postinc"); - prefix("++", "preinc"); - syntax["++"].exps = true; - - suffix("--", "postdec"); - prefix("--", "predec"); - syntax["--"].exps = true; - prefix("delete", function () { - var p = expression(0); - if (!p || (p.id !== "." && p.id !== "[")) { - warning("Variables should not be deleted."); - } - this.first = p; - return this; - }).exps = true; - - prefix("~", function () { - if (option.bitwise) { - warning("Unexpected '{a}'.", this, "~"); - } - expression(150); - return this; - }); - - prefix("!", function () { - this.right = expression(150); - this.arity = "unary"; - if (bang[this.right.id] === true) { - warning("Confusing use of '{a}'.", this, "!"); - } - return this; - }); - prefix("typeof", "typeof"); - prefix("new", function () { - var c = expression(155), i; - if (c && c.id !== "function") { - if (c.identifier) { - c["new"] = true; - switch (c.value) { - case "Number": - case "String": - case "Boolean": - case "Math": - case "JSON": - warning("Do not use {a} as a constructor.", prevtoken, c.value); - break; - case "Function": - if (!option.evil) { - warning("The Function constructor is eval."); - } - break; - case "Date": - case "RegExp": - break; - default: - if (c.id !== "function") { - i = c.value.substr(0, 1); - if (option.newcap && (i < "A" || i > "Z") && !is_own(global, c.value)) { - warning("A constructor name should start with an uppercase letter.", - token); - } - } - } - } else { - if (c.id !== "." && c.id !== "[" && c.id !== "(") { - warning("Bad constructor.", token); - } - } - } else { - if (!option.supernew) - warning("Weird construction. Delete 'new'.", this); - } - adjacent(token, nexttoken); - if (nexttoken.id !== "(" && !option.supernew) { - warning("Missing '()' invoking a constructor.", - token, token.value); - } - this.first = c; - return this; - }); - syntax["new"].exps = true; - - prefix("void").exps = true; - - infix(".", function (left, that) { - adjacent(prevtoken, token); - nobreak(); - var m = identifier(); - if (typeof m === "string") { - countMember(m); - } - that.left = left; - that.right = m; - if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { - if (option.noarg) - warning("Avoid arguments.{a}.", left, m); - else if (directive["use strict"]) - error("Strict violation."); - } else if (!option.evil && left && left.value === "document" && - (m === "write" || m === "writeln")) { - warning("document.write can be a form of eval.", left); - } - if (!option.evil && (m === "eval" || m === "execScript")) { - warning("eval is evil."); - } - return that; - }, 160, true); - - infix("(", function (left, that) { - if (prevtoken.id !== "}" && prevtoken.id !== ")") { - nobreak(prevtoken, token); - } - nospace(); - if (option.immed && !left.immed && left.id === "function") { - warning("Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself."); - } - var n = 0, - p = []; - if (left) { - if (left.type === "(identifier)") { - if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if ("Number String Boolean Date Object".indexOf(left.value) === -1) { - if (left.value === "Math") { - warning("Math is not a function.", left); - } else if (option.newcap) { - warning("Missing 'new' prefix when invoking a constructor.", left); - } - } - } - } - } - if (nexttoken.id !== ")") { - for (;;) { - p[p.length] = expression(10); - n += 1; - if (nexttoken.id !== ",") { - break; - } - comma(); - } - } - advance(")"); - nospace(prevtoken, token); - if (typeof left === "object") { - if (left.value === "parseInt" && n === 1) { - warning("Missing radix parameter.", token); - } - if (!option.evil) { - if (left.value === "eval" || left.value === "Function" || - left.value === "execScript") { - warning("eval is evil.", left); - - if (p[0] && [0].id === "(string)") { - addInternalSrc(left, p[0].value); - } - } else if (p[0] && p[0].id === "(string)" && - (left.value === "setTimeout" || - left.value === "setInterval")) { - warning( - "Implied eval is evil. Pass a function instead of a string.", left); - addInternalSrc(left, p[0].value); - - // window.setTimeout/setInterval - } else if (p[0] && p[0].id === "(string)" && - left.value === "." && - left.left.value === "window" && - (left.right === "setTimeout" || - left.right === "setInterval")) { - warning( - "Implied eval is evil. Pass a function instead of a string.", left); - addInternalSrc(left, p[0].value); - } - } - if (!left.identifier && left.id !== "." && left.id !== "[" && - left.id !== "(" && left.id !== "&&" && left.id !== "||" && - left.id !== "?") { - warning("Bad invocation.", left); - } - } - that.left = left; - return that; - }, 155, true).exps = true; - - prefix("(", function () { - nospace(); - if (nexttoken.id === "function") { - nexttoken.immed = true; - } - var v = expression(0); - advance(")", this); - nospace(prevtoken, token); - if (option.immed && v.id === "function") { - if (nexttoken.id !== "(" && - (nexttoken.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) { - warning( -"Do not wrap function literals in parens unless they are to be immediately invoked.", - this); - } - } - - return v; - }); - - infix("[", function (left, that) { - nobreak(prevtoken, token); - nospace(); - var e = expression(0), s; - if (e && e.type === "(string)") { - if (!option.evil && (e.value === "eval" || e.value === "execScript")) { - warning("eval is evil.", that); - } - countMember(e.value); - if (!option.sub && ix.test(e.value)) { - s = syntax[e.value]; - if (!s || !s.reserved) { - warning("['{a}'] is better written in dot notation.", - prevtoken, e.value); - } - } - } - advance("]", that); - nospace(prevtoken, token); - that.left = left; - that.right = e; - return that; - }, 160, true); - - prefix("[", function () { - var b = token.line !== nexttoken.line; - this.first = []; - if (b) { - indent += option.indent; - if (nexttoken.from === indent + option.indent) { - indent += option.indent; - } - } - while (nexttoken.id !== "(end)") { - while (nexttoken.id === ",") { - if (!option.es5) - warning("Extra comma."); - advance(","); - } - if (nexttoken.id === "]") { - break; - } - if (b && token.line !== nexttoken.line) { - indentation(); - } - this.first.push(expression(10)); - if (nexttoken.id === ",") { - comma(); - if (nexttoken.id === "]" && !option.es5) { - warning("Extra comma.", token); - break; - } - } else { - break; - } - } - if (b) { - indent -= option.indent; - indentation(); - } - advance("]", this); - return this; - }, 160); - - - function property_name() { - var id = optionalidentifier(true); - if (!id) { - if (nexttoken.id === "(string)") { - id = nexttoken.value; - advance(); - } else if (nexttoken.id === "(number)") { - id = nexttoken.value.toString(); - advance(); - } - } - return id; - } - - - function functionparams() { - var next = nexttoken; - var params = []; - var ident; - - advance("("); - nospace(); - - if (nexttoken.id === ")") { - advance(")"); - return; - } - - for (;;) { - ident = identifier(true); - params.push(ident); - addlabel(ident, "unused", token); - if (nexttoken.id === ",") { - comma(); - } else { - advance(")", next); - nospace(prevtoken, token); - return params; - } - } - } - - - function doFunction(name, statement) { - var f; - var oldOption = option; - var oldScope = scope; - - option = Object.create(option); - scope = Object.create(scope); - - funct = { - "(name)" : name || "\"" + anonname + "\"", - "(line)" : nexttoken.line, - "(character)": nexttoken.character, - "(context)" : funct, - "(breakage)" : 0, - "(loopage)" : 0, - "(metrics)" : createMetrics(nexttoken), - "(scope)" : scope, - "(statement)": statement, - "(tokens)" : {} - }; - - f = funct; - token.funct = funct; - - functions.push(funct); - - if (name) { - addlabel(name, "function"); - } - - funct["(params)"] = functionparams(); - funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]); - - block(false, false, true); - - funct["(metrics)"].verifyMaxStatementsPerFunction(); - funct["(metrics)"].verifyMaxComplexityPerFunction(); - - scope = oldScope; - option = oldOption; - funct["(last)"] = token.line; - funct["(lastcharacter)"] = token.character; - funct = funct["(context)"]; - - return f; - } - - function createMetrics(functionStartToken) { - return { - statementCount: 0, - nestedBlockDepth: -1, - ComplexityCount: 1, - verifyMaxStatementsPerFunction: function () { - if (option.maxstatements && - this.statementCount > option.maxstatements) { - var message = "Too many statements per function (" + this.statementCount + ")."; - warning(message, functionStartToken); - } - }, - - verifyMaxParametersPerFunction: function (params) { - params = params || []; - - if (option.maxparams && params.length > option.maxparams) { - var message = "Too many parameters per function (" + params.length + ")."; - warning(message, functionStartToken); - } - }, - - verifyMaxNestedBlockDepthPerFunction: function () { - if (option.maxdepth && - this.nestedBlockDepth > 0 && - this.nestedBlockDepth === option.maxdepth + 1) { - var message = "Blocks are nested too deeply (" + this.nestedBlockDepth + ")."; - warning(message); - } - }, - - verifyMaxComplexityPerFunction: function () { - var max = option.maxcomplexity; - var cc = this.ComplexityCount; - if (max && cc > max) { - var message = "Cyclomatic complexity is too high per function (" + cc + ")."; - warning(message, functionStartToken); - } - } - }; - } - - function increaseComplexityCount() { - funct["(metrics)"].ComplexityCount += 1; - } - - - (function (x) { - x.nud = function () { - var b, f, i, p, t; - var props = {}; // All properties, including accessors - - function saveProperty(name, token) { - if (props[name] && is_own(props, name)) - warning("Duplicate member '{a}'.", nexttoken, i); - else - props[name] = {}; - - props[name].basic = true; - props[name].basicToken = token; - } - - function saveSetter(name, token) { - if (props[name] && is_own(props, name)) { - if (props[name].basic || props[name].setter) - warning("Duplicate member '{a}'.", nexttoken, i); - } else { - props[name] = {}; - } - - props[name].setter = true; - props[name].setterToken = token; - } - - function saveGetter(name) { - if (props[name] && is_own(props, name)) { - if (props[name].basic || props[name].getter) - warning("Duplicate member '{a}'.", nexttoken, i); - } else { - props[name] = {}; - } - - props[name].getter = true; - props[name].getterToken = token; - } - - b = token.line !== nexttoken.line; - if (b) { - indent += option.indent; - if (nexttoken.from === indent + option.indent) { - indent += option.indent; - } - } - for (;;) { - if (nexttoken.id === "}") { - break; - } - if (b) { - indentation(); - } - if (nexttoken.value === "get" && peek().id !== ":") { - advance("get"); - if (!option.es5) { - error("get/set are ES5 features."); - } - i = property_name(); - if (!i) { - error("Missing property name."); - } - saveGetter(i); - t = nexttoken; - adjacent(token, nexttoken); - f = doFunction(); - p = f["(params)"]; - if (p) { - warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i); - } - adjacent(token, nexttoken); - } else if (nexttoken.value === "set" && peek().id !== ":") { - advance("set"); - if (!option.es5) { - error("get/set are ES5 features."); - } - i = property_name(); - if (!i) { - error("Missing property name."); - } - saveSetter(i, nexttoken); - t = nexttoken; - adjacent(token, nexttoken); - f = doFunction(); - p = f["(params)"]; - if (!p || p.length !== 1) { - warning("Expected a single parameter in set {a} function.", t, i); - } - } else { - i = property_name(); - saveProperty(i, nexttoken); - if (typeof i !== "string") { - break; - } - advance(":"); - nonadjacent(token, nexttoken); - expression(10); - } - - countMember(i); - if (nexttoken.id === ",") { - comma(); - if (nexttoken.id === ",") { - warning("Extra comma.", token); - } else if (nexttoken.id === "}" && !option.es5) { - warning("Extra comma.", token); - } - } else { - break; - } - } - if (b) { - indent -= option.indent; - indentation(); - } - advance("}", this); - - // Check for lonely setters if in the ES5 mode. - if (option.es5) { - for (var name in props) { - if (is_own(props, name) && props[name].setter && !props[name].getter) { - warning("Setter is defined without getter.", props[name].setterToken); - } - } - } - return this; - }; - x.fud = function () { - error("Expected to see a statement and instead saw a block.", token); - }; - }(delim("{"))); - -// This Function is called when esnext option is set to true -// it adds the `const` statement to JSHINT - - useESNextSyntax = function () { - var conststatement = stmt("const", function (prefix) { - var id, name, value; - - this.first = []; - for (;;) { - nonadjacent(token, nexttoken); - id = identifier(); - if (funct[id] === "const") { - warning("const '" + id + "' has already been declared"); - } - if (funct["(global)"] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); - } - addlabel(id, "const"); - if (prefix) { - break; - } - name = token; - this.first.push(token); - - if (nexttoken.id !== "=") { - warning("const " + - "'{a}' is initialized to 'undefined'.", token, id); - } - - if (nexttoken.id === "=") { - nonadjacent(token, nexttoken); - advance("="); - nonadjacent(token, nexttoken); - if (nexttoken.id === "undefined") { - warning("It is not necessary to initialize " + - "'{a}' to 'undefined'.", token, id); - } - if (peek(0).id === "=" && nexttoken.identifier) { - error("Constant {a} was not declared correctly.", - nexttoken, nexttoken.value); - } - value = expression(0); - name.first = value; - } - - if (nexttoken.id !== ",") { - break; - } - comma(); - } - return this; - }); - conststatement.exps = true; - }; - - var varstatement = stmt("var", function (prefix) { - // JavaScript does not have block scope. It only has function scope. So, - // declaring a variable in a block can have unexpected consequences. - var id, name, value; - - if (funct["(onevar)"] && option.onevar) { - warning("Too many var statements."); - } else if (!funct["(global)"]) { - funct["(onevar)"] = true; - } - - this.first = []; - - for (;;) { - nonadjacent(token, nexttoken); - id = identifier(); - - if (option.esnext && funct[id] === "const") { - warning("const '" + id + "' has already been declared"); - } - - if (funct["(global)"] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); - } - - addlabel(id, "unused", token); - - if (prefix) { - break; - } - - name = token; - this.first.push(token); - - if (nexttoken.id === "=") { - nonadjacent(token, nexttoken); - advance("="); - nonadjacent(token, nexttoken); - if (nexttoken.id === "undefined") { - warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id); - } - if (peek(0).id === "=" && nexttoken.identifier) { - error("Variable {a} was not declared correctly.", - nexttoken, nexttoken.value); - } - value = expression(0); - name.first = value; - } - if (nexttoken.id !== ",") { - break; - } - comma(); - } - return this; - }); - varstatement.exps = true; - - blockstmt("function", function () { - if (inblock) { - warning("Function declarations should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", token); - - } - var i = identifier(); - if (option.esnext && funct[i] === "const") { - warning("const '" + i + "' has already been declared"); - } - adjacent(token, nexttoken); - addlabel(i, "unction", token); - - doFunction(i, { statement: true }); - if (nexttoken.id === "(" && nexttoken.line === token.line) { - error( -"Function declarations are not invocable. Wrap the whole function invocation in parens."); - } - return this; - }); - - prefix("function", function () { - var i = optionalidentifier(); - if (i) { - adjacent(token, nexttoken); - } else { - nonadjacent(token, nexttoken); - } - doFunction(i); - if (!option.loopfunc && funct["(loopage)"]) { - warning("Don't make functions within a loop."); - } - return this; - }); - - blockstmt("if", function () { - var t = nexttoken; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance("="); - expression(20); - } - advance(")", t); - nospace(prevtoken, token); - block(true, true); - if (nexttoken.id === "else") { - nonadjacent(token, nexttoken); - advance("else"); - if (nexttoken.id === "if" || nexttoken.id === "switch") { - statement(true); - } else { - block(true, true); - } - } - return this; - }); - - blockstmt("try", function () { - var b; - - function doCatch() { - var oldScope = scope; - var e; - - advance("catch"); - nonadjacent(token, nexttoken); - advance("("); - - scope = Object.create(oldScope); - - e = nexttoken.value; - if (nexttoken.type !== "(identifier)") { - e = null; - warning("Expected an identifier and instead saw '{a}'.", nexttoken, e); - } - - advance(); - advance(")"); - - funct = { - "(name)" : "(catch)", - "(line)" : nexttoken.line, - "(character)": nexttoken.character, - "(context)" : funct, - "(breakage)" : funct["(breakage)"], - "(loopage)" : funct["(loopage)"], - "(scope)" : scope, - "(statement)": false, - "(metrics)" : createMetrics(nexttoken), - "(catch)" : true, - "(tokens)" : {} - }; - - if (e) { - addlabel(e, "exception"); - } - - token.funct = funct; - functions.push(funct); - - block(false); - - scope = oldScope; - - funct["(last)"] = token.line; - funct["(lastcharacter)"] = token.character; - funct = funct["(context)"]; - } - - block(false); - - if (nexttoken.id === "catch") { - increaseComplexityCount(); - doCatch(); - b = true; - } - - if (nexttoken.id === "finally") { - advance("finally"); - block(false); - return; - } else if (!b) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, "catch", nexttoken.value); - } - - return this; - }); - - blockstmt("while", function () { - var t = nexttoken; - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance("="); - expression(20); - } - advance(")", t); - nospace(prevtoken, token); - block(true, true); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - }).labelled = true; - - blockstmt("with", function () { - var t = nexttoken; - if (directive["use strict"]) { - error("'with' is not allowed in strict mode.", token); - } else if (!option.withstmt) { - warning("Don't use 'with'.", token); - } - - advance("("); - nonadjacent(this, t); - nospace(); - expression(0); - advance(")", t); - nospace(prevtoken, token); - block(true, true); - - return this; - }); - - blockstmt("switch", function () { - var t = nexttoken, - g = false; - funct["(breakage)"] += 1; - advance("("); - nonadjacent(this, t); - nospace(); - this.condition = expression(20); - advance(")", t); - nospace(prevtoken, token); - nonadjacent(token, nexttoken); - t = nexttoken; - advance("{"); - nonadjacent(token, nexttoken); - indent += option.indent; - this.cases = []; - for (;;) { - switch (nexttoken.id) { - case "case": - switch (funct["(verb)"]) { - case "break": - case "case": - case "continue": - case "return": - case "switch": - case "throw": - break; - default: - // You can tell JSHint that you don't use break intentionally by - // adding a comment /* falls through */ on a line just before - // the next `case`. - if (!ft.test(lines[nexttoken.line - 2])) { - warning( - "Expected a 'break' statement before 'case'.", - token); - } - } - indentation(-option.indent); - advance("case"); - this.cases.push(expression(20)); - increaseComplexityCount(); - g = true; - advance(":"); - funct["(verb)"] = "case"; - break; - case "default": - switch (funct["(verb)"]) { - case "break": - case "continue": - case "return": - case "throw": - break; - default: - if (!ft.test(lines[nexttoken.line - 2])) { - warning( - "Expected a 'break' statement before 'default'.", - token); - } - } - indentation(-option.indent); - advance("default"); - g = true; - advance(":"); - break; - case "}": - indent -= option.indent; - indentation(); - advance("}", t); - if (this.cases.length === 1 || this.condition.id === "true" || - this.condition.id === "false") { - if (!option.onecase) - warning("This 'switch' should be an 'if'.", this); - } - funct["(breakage)"] -= 1; - funct["(verb)"] = undefined; - return; - case "(end)": - error("Missing '{a}'.", nexttoken, "}"); - return; - default: - if (g) { - switch (token.id) { - case ",": - error("Each value should have its own case label."); - return; - case ":": - g = false; - statements(); - break; - default: - error("Missing ':' on a case clause.", token); - return; - } - } else { - if (token.id === ":") { - advance(":"); - error("Unexpected '{a}'.", token, ":"); - statements(); - } else { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, "case", nexttoken.value); - return; - } - } - } - } - }).labelled = true; - - stmt("debugger", function () { - if (!option.debug) { - warning("All 'debugger' statements should be removed."); - } - return this; - }).exps = true; - - (function () { - var x = stmt("do", function () { - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - - this.first = block(true); - advance("while"); - var t = nexttoken; - nonadjacent(token, t); - advance("("); - nospace(); - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance("="); - expression(20); - } - advance(")", t); - nospace(prevtoken, token); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - }); - x.labelled = true; - x.exps = true; - }()); - - blockstmt("for", function () { - var s, t = nexttoken; - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - if (peek(nexttoken.id === "var" ? 1 : 0).id === "in") { - if (nexttoken.id === "var") { - advance("var"); - varstatement.fud.call(varstatement, true); - } else { - switch (funct[nexttoken.value]) { - case "unused": - funct[nexttoken.value] = "var"; - break; - case "var": - break; - default: - warning("Bad for in variable '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - advance("in"); - expression(20); - advance(")", t); - s = block(true, true); - if (option.forin && s && (s.length > 1 || typeof s[0] !== "object" || - s[0].value !== "if")) { - warning("The body of a for in should be wrapped in an if statement to filter " + - "unwanted properties from the prototype.", this); - } - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - } else { - if (nexttoken.id !== ";") { - if (nexttoken.id === "var") { - advance("var"); - varstatement.fud.call(varstatement); - } else { - for (;;) { - expression(0, "for"); - if (nexttoken.id !== ",") { - break; - } - comma(); - } - } - } - nolinebreak(token); - advance(";"); - if (nexttoken.id !== ";") { - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance("="); - expression(20); - } - } - nolinebreak(token); - advance(";"); - if (nexttoken.id === ";") { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, ")", ";"); - } - if (nexttoken.id !== ")") { - for (;;) { - expression(0, "for"); - if (nexttoken.id !== ",") { - break; - } - comma(); - } - } - advance(")", t); - nospace(prevtoken, token); - block(true, true); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - } - }).labelled = true; - - - stmt("break", function () { - var v = nexttoken.value; - - if (funct["(breakage)"] === 0) - warning("Unexpected '{a}'.", nexttoken, this.value); - - if (!option.asi) - nolinebreak(this); - - if (nexttoken.id !== ";") { - if (token.line === nexttoken.line) { - if (funct[v] !== "label") { - warning("'{a}' is not a statement label.", nexttoken, v); - } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); - } - this.first = nexttoken; - advance(); - } - } - reachable("break"); - return this; - }).exps = true; - - - stmt("continue", function () { - var v = nexttoken.value; - - if (funct["(breakage)"] === 0) - warning("Unexpected '{a}'.", nexttoken, this.value); - - if (!option.asi) - nolinebreak(this); - - if (nexttoken.id !== ";") { - if (token.line === nexttoken.line) { - if (funct[v] !== "label") { - warning("'{a}' is not a statement label.", nexttoken, v); - } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); - } - this.first = nexttoken; - advance(); - } - } else if (!funct["(loopage)"]) { - warning("Unexpected '{a}'.", nexttoken, this.value); - } - reachable("continue"); - return this; - }).exps = true; - - - stmt("return", function () { - if (this.line === nexttoken.line) { - if (nexttoken.id === "(regexp)") - warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); - - if (nexttoken.id !== ";" && !nexttoken.reach) { - nonadjacent(token, nexttoken); - if (peek().value === "=" && !option.boss) { - warningAt("Did you mean to return a conditional instead of an assignment?", - token.line, token.character + 1); - } - this.first = expression(0); - } - } else if (!option.asi) { - nolinebreak(this); // always warn (Line breaking error) - } - reachable("return"); - return this; - }).exps = true; - - - stmt("throw", function () { - nolinebreak(this); - nonadjacent(token, nexttoken); - this.first = expression(20); - reachable("throw"); - return this; - }).exps = true; - -// Superfluous reserved words - - reserve("class"); - reserve("const"); - reserve("enum"); - reserve("export"); - reserve("extends"); - reserve("import"); - reserve("super"); - - reserve("let"); - reserve("yield"); - reserve("implements"); - reserve("interface"); - reserve("package"); - reserve("private"); - reserve("protected"); - reserve("public"); - reserve("static"); - - -// Parse JSON - - function jsonValue() { - - function jsonObject() { - var o = {}, t = nexttoken; - advance("{"); - if (nexttoken.id !== "}") { - for (;;) { - if (nexttoken.id === "(end)") { - error("Missing '}' to match '{' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === "}") { - warning("Unexpected comma.", token); - break; - } else if (nexttoken.id === ",") { - error("Unexpected comma.", nexttoken); - } else if (nexttoken.id !== "(string)") { - warning("Expected a string and instead saw {a}.", - nexttoken, nexttoken.value); - } - if (o[nexttoken.value] === true) { - warning("Duplicate key '{a}'.", - nexttoken, nexttoken.value); - } else if ((nexttoken.value === "__proto__" && - !option.proto) || (nexttoken.value === "__iterator__" && - !option.iterator)) { - warning("The '{a}' key may produce unexpected results.", - nexttoken, nexttoken.value); - } else { - o[nexttoken.value] = true; - } - advance(); - advance(":"); - jsonValue(); - if (nexttoken.id !== ",") { - break; - } - advance(","); - } - } - advance("}"); - } - - function jsonArray() { - var t = nexttoken; - advance("["); - if (nexttoken.id !== "]") { - for (;;) { - if (nexttoken.id === "(end)") { - error("Missing ']' to match '[' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === "]") { - warning("Unexpected comma.", token); - break; - } else if (nexttoken.id === ",") { - error("Unexpected comma.", nexttoken); - } - jsonValue(); - if (nexttoken.id !== ",") { - break; - } - advance(","); - } - } - advance("]"); - } - - switch (nexttoken.id) { - case "{": - jsonObject(); - break; - case "[": - jsonArray(); - break; - case "true": - case "false": - case "null": - case "(number)": - case "(string)": - advance(); - break; - case "-": - advance("-"); - if (token.character !== nexttoken.from) { - warning("Unexpected space after '-'.", token); - } - adjacent(token, nexttoken); - advance("(number)"); - break; - default: - error("Expected a JSON value.", nexttoken); - } - } - - - // The actual JSHINT function itself. - var itself = function (s, o, g) { - var a, i, k, x; - var optionKeys; - var newOptionObj = {}; - - if (o && o.scope) { - JSHINT.scope = o.scope; - } else { - JSHINT.errors = []; - JSHINT.undefs = []; - JSHINT.internals = []; - JSHINT.blacklist = {}; - JSHINT.scope = "(main)"; - } - - predefined = Object.create(standard); - declared = Object.create(null); - combine(predefined, g || {}); - - if (o) { - a = o.predef; - if (a) { - if (!Array.isArray(a) && typeof a === "object") { - a = Object.keys(a); - } - a.forEach(function (item) { - var slice; - if (item[0] === "-") { - slice = item.slice(1); - JSHINT.blacklist[slice] = slice; - } else { - predefined[item] = true; - } - }); - } - - optionKeys = Object.keys(o); - for (x = 0; x < optionKeys.length; x++) { - newOptionObj[optionKeys[x]] = o[optionKeys[x]]; - - if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) - newOptionObj["(explicitNewcap)"] = true; - - if (optionKeys[x] === "indent") - newOptionObj.white = true; - } - } - - option = newOptionObj; - - option.indent = option.indent || 4; - option.maxerr = option.maxerr || 50; - - tab = ""; - for (i = 0; i < option.indent; i += 1) { - tab += " "; - } - indent = 1; - global = Object.create(predefined); - scope = global; - funct = { - "(global)": true, - "(name)": "(global)", - "(scope)": scope, - "(breakage)": 0, - "(loopage)": 0, - "(tokens)": {}, - "(metrics)": createMetrics(nexttoken) - }; - functions = [funct]; - urls = []; - stack = null; - member = {}; - membersOnly = null; - implied = {}; - inblock = false; - lookahead = []; - jsonmode = false; - warnings = 0; - lines = []; - unuseds = []; - - if (!isString(s) && !Array.isArray(s)) { - errorAt("Input is neither a string nor an array of strings.", 0); - return false; - } - - if (isString(s) && /^\s*$/g.test(s)) { - errorAt("Input is an empty string.", 0); - return false; - } - - if (s.length === 0) { - errorAt("Input is an empty array.", 0); - return false; - } - - lex.init(s); - - prereg = true; - directive = {}; - - prevtoken = token = nexttoken = syntax["(begin)"]; - - // Check options - for (var name in o) { - if (is_own(o, name)) { - checkOption(name, token); - } - } - - assume(); - - // combine the passed globals after we've assumed all our options - combine(predefined, g || {}); - - //reset values - comma.first = true; - quotmark = undefined; - - try { - advance(); - switch (nexttoken.id) { - case "{": - case "[": - option.laxbreak = true; - jsonmode = true; - jsonValue(); - break; - default: - directives(); - if (directive["use strict"] && !option.globalstrict) { - warning("Use the function form of \"use strict\".", prevtoken); - } - - statements(); - } - advance((nexttoken && nexttoken.value !== ".") ? "(end)" : undefined); - - var markDefined = function (name, context) { - do { - if (typeof context[name] === "string") { - // JSHINT marks unused variables as 'unused' and - // unused function declaration as 'unction'. This - // code changes such instances back 'var' and - // 'closure' so that the code in JSHINT.data() - // doesn't think they're unused. - - if (context[name] === "unused") - context[name] = "var"; - else if (context[name] === "unction") - context[name] = "closure"; - - return true; - } - - context = context["(context)"]; - } while (context); - - return false; - }; - - var clearImplied = function (name, line) { - if (!implied[name]) - return; - - var newImplied = []; - for (var i = 0; i < implied[name].length; i += 1) { - if (implied[name][i] !== line) - newImplied.push(implied[name][i]); - } - - if (newImplied.length === 0) - delete implied[name]; - else - implied[name] = newImplied; - }; - - var warnUnused = function (name, token) { - var line = token.line; - var chr = token.character; - - if (option.unused) - warningAt("'{a}' is defined but never used.", line, chr, name); - - unuseds.push({ - name: name, - line: line, - character: chr - }); - }; - - var checkUnused = function (func, key) { - var type = func[key]; - var token = func["(tokens)"][key]; - - if (key.charAt(0) === "(") - return; - - if (type !== "unused" && type !== "unction") - return; - - // Params are checked separately from other variables. - if (func["(params)"] && func["(params)"].indexOf(key) !== -1) - return; - - warnUnused(key, token); - }; - - // Check queued 'x is not defined' instances to see if they're still undefined. - for (i = 0; i < JSHINT.undefs.length; i += 1) { - k = JSHINT.undefs[i].slice(0); - - if (markDefined(k[2].value, k[0])) { - clearImplied(k[2].value, k[2].line); - } else { - warning.apply(warning, k.slice(1)); - } - } - - functions.forEach(function (func) { - for (var key in func) { - if (is_own(func, key)) { - checkUnused(func, key); - } - } - - if (!func["(params)"]) - return; - - var params = func["(params)"].slice(); - var param = params.pop(); - var type; - - while (param) { - type = func[param]; - - // 'undefined' is a special case for (function (window, undefined) { ... })(); - // patterns. - - if (param === "undefined") - return; - - if (type !== "unused" && type !== "unction") - return; - - warnUnused(param, func["(tokens)"][param]); - param = params.pop(); - } - }); - - for (var key in declared) { - if (is_own(declared, key) && !is_own(global, key)) { - warnUnused(key, declared[key]); - } - } - } catch (e) { - if (e) { - var nt = nexttoken || {}; - JSHINT.errors.push({ - raw : e.raw, - reason : e.message, - line : e.line || nt.line, - character : e.character || nt.from - }, null); - } - } - - // Loop over the listed "internals", and check them as well. - - if (JSHINT.scope === "(main)") { - o = o || {}; - - for (i = 0; i < JSHINT.internals.length; i += 1) { - k = JSHINT.internals[i]; - o.scope = k.elem; - itself(k.value, o, g); - } - } - - return JSHINT.errors.length === 0; - }; - - // Data summary. - itself.data = function () { - var data = { - functions: [], - options: option - }; - var implieds = []; - var members = []; - var fu, f, i, j, n, globals; - - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (jsonmode) { - data.json = true; - } - - for (n in implied) { - if (is_own(implied, n)) { - implieds.push({ - name: n, - line: implied[n] - }); - } - } - - if (implieds.length > 0) { - data.implieds = implieds; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(scope); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - f = functions[i]; - fu = {}; - - for (j = 0; j < functionicity.length; j += 1) { - fu[functionicity[j]] = []; - } - - for (j = 0; j < functionicity.length; j += 1) { - if (fu[functionicity[j]].length === 0) { - delete fu[functionicity[j]]; - } - } - - fu.name = f["(name)"]; - fu.param = f["(params)"]; - fu.line = f["(line)"]; - fu.character = f["(character)"]; - fu.last = f["(last)"]; - fu.lastcharacter = f["(lastcharacter)"]; - data.functions.push(fu); - } - - if (unuseds.length > 0) { - data.unused = unuseds; - } - - members = []; - for (n in member) { - if (typeof member[n] === "number") { - data.member = member; - break; - } - } - - return data; - }; - - itself.jshint = itself; - - return itself; -}()); - -// Make JSHINT a Node module, if possible. -if (typeof exports === "object" && exports) { - exports.JSHINT = JSHINT; -} diff --git a/rsc/scripts/jsdoc/node_modules/markdown/README.markdown b/rsc/scripts/jsdoc/node_modules/markdown/README.markdown deleted file mode 100644 index 67f39696..00000000 --- a/rsc/scripts/jsdoc/node_modules/markdown/README.markdown +++ /dev/null @@ -1,115 +0,0 @@ -markdown-js -=========== - -Yet another markdown parser, this time for JavaScript. There's a few -options that precede this project but they all treat markdown to HTML -conversion as a single step process. You pass markdown in and get HTML -out, end of story. We had some pretty particular views on how the -process should actually look, which include: - - * producing well-formed HTML. This means that em and strong nesting is - important, as is the ability to output as both HTML and XHTML - - * having an intermediate representation to allow processing of parsed - data (we in fact have two, both [JsonML]: a markdown tree and an - HTML tree) - - * being easily extensible to add new dialects without having to - rewrite the entire parsing mechanics - - * having a good test suite. The only test suites we could find tested - massive blocks of input, and passing depended on outputting the HTML - with exactly the same whitespace as the original implementation - -[JsonML]: http://jsonml.org/ "JSON Markup Language" - -## Installation - -Just the `markdown` library: - - npm install markdown - -Also install `md2html` to `/usr/local/bin` (or wherever) - - npm install -g markdown - -## Usage - -The simple way to use it with CommonJS is: - - var input = "# Heading\n\nParagraph"; - var output = require( "markdown" ).markdown.toHTML( input ); - print( output ); - -If you want more control check out the documentation in -[lib/markdown.js] which details all the methods and parameters -available (including examples!). One day we'll get the docs generated -and hosted somewhere for nicer browsing. - -It also works in a browser; here is a complete example: - - - - - -
- - - - - -### md2html - - md2html /path/to/doc.md > /path/to/doc.html - -[lib/markdown.js]: http://github.com/evilstreak/markdown-js/blob/master/lib/markdown.js - -## Intermediate Representation - -Internally the process to convert a chunk of markdown into a chunk of -HTML has three steps: - - 1. Parse the markdown into a JsonML tree. Any references found in the - parsing are stored in the attribute hash of the root node under the - key `references`. - - 2. Convert the markdown tree into an HTML tree. Rename any nodes that - need it (`bulletlist` to `ul` for example) and lookup any references - used by links or images. Remove the references attribute once done. - - 3. Stringify the HTML tree being careful not to wreck whitespace where - whitespace is important (surrounding inline elements for example). - -Each step of this process can be called individually if you need to do -some processing or modification of the data at an intermediate stage. -For example, you may want to grab a list of all URLs linked to in the -document before rendering it to HTML which you could do by recursing -through the HTML tree looking for `a` nodes. - -## Running tests - -To run the tests under node you will need tap installed (it's listed as a -devDependencies so `npm install` from the checkout should be enough), then do - - $ ./node_modules/.bin/tap test/*.t.js - -## Contributing - -Do the usual github fork and pull request dance. Add yourself to the -contributors section of package.json too if you want to. - -## License - -Released under the MIT license. diff --git a/rsc/scripts/jsdoc/node_modules/markdown/lib/index.js b/rsc/scripts/jsdoc/node_modules/markdown/lib/index.js deleted file mode 100644 index 8bb08734..00000000 --- a/rsc/scripts/jsdoc/node_modules/markdown/lib/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// super simple module for the most common nodejs use case. -exports.markdown = require("./markdown"); -exports.parse = exports.markdown.toHTML; diff --git a/rsc/scripts/jsdoc/node_modules/markdown/lib/markdown.js b/rsc/scripts/jsdoc/node_modules/markdown/lib/markdown.js deleted file mode 100644 index 817cfddc..00000000 --- a/rsc/scripts/jsdoc/node_modules/markdown/lib/markdown.js +++ /dev/null @@ -1,1616 +0,0 @@ -// Released under MIT license -// Copyright (c) 2009-2010 Dominic Baggott -// Copyright (c) 2009-2010 Ash Berlin -// Copyright (c) 2011 Christoph Dorn (http://www.christophdorn.com) - -(function( expose ) { - -/** - * class Markdown - * - * Markdown processing in Javascript done right. We have very particular views - * on what constitutes 'right' which include: - * - * - produces well-formed HTML (this means that em and strong nesting is - * important) - * - * - has an intermediate representation to allow processing of parsed data (We - * in fact have two, both as [JsonML]: a markdown tree and an HTML tree). - * - * - is easily extensible to add new dialects without having to rewrite the - * entire parsing mechanics - * - * - has a good test suite - * - * This implementation fulfills all of these (except that the test suite could - * do with expanding to automatically run all the fixtures from other Markdown - * implementations.) - * - * ##### Intermediate Representation - * - * *TODO* Talk about this :) Its JsonML, but document the node names we use. - * - * [JsonML]: http://jsonml.org/ "JSON Markup Language" - **/ -var Markdown = expose.Markdown = function Markdown(dialect) { - switch (typeof dialect) { - case "undefined": - this.dialect = Markdown.dialects.Gruber; - break; - case "object": - this.dialect = dialect; - break; - default: - if (dialect in Markdown.dialects) { - this.dialect = Markdown.dialects[dialect]; - } - else { - throw new Error("Unknown Markdown dialect '" + String(dialect) + "'"); - } - break; - } - this.em_state = []; - this.strong_state = []; - this.debug_indent = ""; -}; - -/** - * parse( markdown, [dialect] ) -> JsonML - * - markdown (String): markdown string to parse - * - dialect (String | Dialect): the dialect to use, defaults to gruber - * - * Parse `markdown` and return a markdown document as a Markdown.JsonML tree. - **/ -expose.parse = function( source, dialect ) { - // dialect will default if undefined - var md = new Markdown( dialect ); - return md.toTree( source ); -}; - -/** - * toHTML( markdown, [dialect] ) -> String - * toHTML( md_tree ) -> String - * - markdown (String): markdown string to parse - * - md_tree (Markdown.JsonML): parsed markdown tree - * - * Take markdown (either as a string or as a JsonML tree) and run it through - * [[toHTMLTree]] then turn it into a well-formated HTML fragment. - **/ -expose.toHTML = function toHTML( source , dialect , options ) { - var input = expose.toHTMLTree( source , dialect , options ); - - return expose.renderJsonML( input ); -}; - -/** - * toHTMLTree( markdown, [dialect] ) -> JsonML - * toHTMLTree( md_tree ) -> JsonML - * - markdown (String): markdown string to parse - * - dialect (String | Dialect): the dialect to use, defaults to gruber - * - md_tree (Markdown.JsonML): parsed markdown tree - * - * Turn markdown into HTML, represented as a JsonML tree. If a string is given - * to this function, it is first parsed into a markdown tree by calling - * [[parse]]. - **/ -expose.toHTMLTree = function toHTMLTree( input, dialect , options ) { - // convert string input to an MD tree - if ( typeof input ==="string" ) input = this.parse( input, dialect ); - - // Now convert the MD tree to an HTML tree - - // remove references from the tree - var attrs = extract_attr( input ), - refs = {}; - - if ( attrs && attrs.references ) { - refs = attrs.references; - } - - var html = convert_tree_to_html( input, refs , options ); - merge_text_nodes( html ); - return html; -}; - -// For Spidermonkey based engines -function mk_block_toSource() { - return "Markdown.mk_block( " + - uneval(this.toString()) + - ", " + - uneval(this.trailing) + - ", " + - uneval(this.lineNumber) + - " )"; -} - -// node -function mk_block_inspect() { - var util = require('util'); - return "Markdown.mk_block( " + - util.inspect(this.toString()) + - ", " + - util.inspect(this.trailing) + - ", " + - util.inspect(this.lineNumber) + - " )"; - -} - -var mk_block = Markdown.mk_block = function(block, trail, line) { - // Be helpful for default case in tests. - if ( arguments.length == 1 ) trail = "\n\n"; - - var s = new String(block); - s.trailing = trail; - // To make it clear its not just a string - s.inspect = mk_block_inspect; - s.toSource = mk_block_toSource; - - if (line != undefined) - s.lineNumber = line; - - return s; -}; - -function count_lines( str ) { - var n = 0, i = -1; - while ( ( i = str.indexOf('\n', i+1) ) !== -1) n++; - return n; -} - -// Internal - split source into rough blocks -Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) { - // [\s\S] matches _anything_ (newline or space) - var re = /([\s\S]+?)($|\n(?:\s*\n|$)+)/g, - blocks = [], - m; - - var line_no = 1; - - if ( ( m = /^(\s*\n)/.exec(input) ) != null ) { - // skip (but count) leading blank lines - line_no += count_lines( m[0] ); - re.lastIndex = m[0].length; - } - - while ( ( m = re.exec(input) ) !== null ) { - blocks.push( mk_block( m[1], m[2], line_no ) ); - line_no += count_lines( m[0] ); - } - - return blocks; -}; - -/** - * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ] - * - block (String): the block to process - * - next (Array): the following blocks - * - * Process `block` and return an array of JsonML nodes representing `block`. - * - * It does this by asking each block level function in the dialect to process - * the block until one can. Succesful handling is indicated by returning an - * array (with zero or more JsonML nodes), failure by a false value. - * - * Blocks handlers are responsible for calling [[Markdown#processInline]] - * themselves as appropriate. - * - * If the blocks were split incorrectly or adjacent blocks need collapsing you - * can adjust `next` in place using shift/splice etc. - * - * If any of this default behaviour is not right for the dialect, you can - * define a `__call__` method on the dialect that will get invoked to handle - * the block processing. - */ -Markdown.prototype.processBlock = function processBlock( block, next ) { - var cbs = this.dialect.block, - ord = cbs.__order__; - - if ( "__call__" in cbs ) { - return cbs.__call__.call(this, block, next); - } - - for ( var i = 0; i < ord.length; i++ ) { - //D:this.debug( "Testing", ord[i] ); - var res = cbs[ ord[i] ].call( this, block, next ); - if ( res ) { - //D:this.debug(" matched"); - if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) ) - this.debug(ord[i], "didn't return a proper array"); - //D:this.debug( "" ); - return res; - } - } - - // Uhoh! no match! Should we throw an error? - return []; -}; - -Markdown.prototype.processInline = function processInline( block ) { - return this.dialect.inline.__call__.call( this, String( block ) ); -}; - -/** - * Markdown#toTree( source ) -> JsonML - * - source (String): markdown source to parse - * - * Parse `source` into a JsonML tree representing the markdown document. - **/ -// custom_tree means set this.tree to `custom_tree` and restore old value on return -Markdown.prototype.toTree = function toTree( source, custom_root ) { - var blocks = source instanceof Array ? source : this.split_blocks( source ); - - // Make tree a member variable so its easier to mess with in extensions - var old_tree = this.tree; - try { - this.tree = custom_root || this.tree || [ "markdown" ]; - - blocks: - while ( blocks.length ) { - var b = this.processBlock( blocks.shift(), blocks ); - - // Reference blocks and the like won't return any content - if ( !b.length ) continue blocks; - - this.tree.push.apply( this.tree, b ); - } - return this.tree; - } - finally { - if ( custom_root ) { - this.tree = old_tree; - } - } -}; - -// Noop by default -Markdown.prototype.debug = function () { - var args = Array.prototype.slice.call( arguments); - args.unshift(this.debug_indent); - if (typeof print !== "undefined") - print.apply( print, args ); - if (typeof console !== "undefined" && typeof console.log !== "undefined") - console.log.apply( null, args ); -} - -Markdown.prototype.loop_re_over_block = function( re, block, cb ) { - // Dont use /g regexps with this - var m, - b = block.valueOf(); - - while ( b.length && (m = re.exec(b) ) != null) { - b = b.substr( m[0].length ); - cb.call(this, m); - } - return b; -}; - -/** - * Markdown.dialects - * - * Namespace of built-in dialects. - **/ -Markdown.dialects = {}; - -/** - * Markdown.dialects.Gruber - * - * The default dialect that follows the rules set out by John Gruber's - * markdown.pl as closely as possible. Well actually we follow the behaviour of - * that script which in some places is not exactly what the syntax web page - * says. - **/ -Markdown.dialects.Gruber = { - block: { - atxHeader: function atxHeader( block, next ) { - var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ ); - - if ( !m ) return undefined; - - var header = [ "header", { level: m[ 1 ].length } ]; - Array.prototype.push.apply(header, this.processInline(m[ 2 ])); - - if ( m[0].length < block.length ) - next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) ); - - return [ header ]; - }, - - setextHeader: function setextHeader( block, next ) { - var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ ); - - if ( !m ) return undefined; - - var level = ( m[ 2 ] === "=" ) ? 1 : 2; - var header = [ "header", { level : level }, m[ 1 ] ]; - - if ( m[0].length < block.length ) - next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) ); - - return [ header ]; - }, - - code: function code( block, next ) { - // | Foo - // |bar - // should be a code block followed by a paragraph. Fun - // - // There might also be adjacent code block to merge. - - var ret = [], - re = /^(?: {0,3}\t| {4})(.*)\n?/, - lines; - - // 4 spaces + content - if ( !block.match( re ) ) return undefined; - - block_search: - do { - // Now pull out the rest of the lines - var b = this.loop_re_over_block( - re, block.valueOf(), function( m ) { ret.push( m[1] ); } ); - - if (b.length) { - // Case alluded to in first comment. push it back on as a new block - next.unshift( mk_block(b, block.trailing) ); - break block_search; - } - else if (next.length) { - // Check the next block - it might be code too - if ( !next[0].match( re ) ) break block_search; - - // Pull how how many blanks lines follow - minus two to account for .join - ret.push ( block.trailing.replace(/[^\n]/g, '').substring(2) ); - - block = next.shift(); - } - else { - break block_search; - } - } while (true); - - return [ [ "code_block", ret.join("\n") ] ]; - }, - - horizRule: function horizRule( block, next ) { - // this needs to find any hr in the block to handle abutting blocks - var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ ); - - if ( !m ) { - return undefined; - } - - var jsonml = [ [ "hr" ] ]; - - // if there's a leading abutting block, process it - if ( m[ 1 ] ) { - jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) ); - } - - // if there's a trailing abutting block, stick it into next - if ( m[ 3 ] ) { - next.unshift( mk_block( m[ 3 ] ) ); - } - - return jsonml; - }, - - // There are two types of lists. Tight and loose. Tight lists have no whitespace - // between the items (and result in text just in the
  • ) and loose lists, - // which have an empty line between list items, resulting in (one or more) - // paragraphs inside the
  • . - // - // There are all sorts weird edge cases about the original markdown.pl's - // handling of lists: - // - // * Nested lists are supposed to be indented by four chars per level. But - // if they aren't, you can get a nested list by indenting by less than - // four so long as the indent doesn't match an indent of an existing list - // item in the 'nest stack'. - // - // * The type of the list (bullet or number) is controlled just by the - // first item at the indent. Subsequent changes are ignored unless they - // are for nested lists - // - lists: (function( ) { - // Use a closure to hide a few variables. - var any_list = "[*+-]|\\d+\\.", - bullet_list = /[*+-]/, - number_list = /\d+\./, - // Capture leading indent as it matters for determining nested lists. - is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ), - indent_re = "(?: {0,3}\\t| {4})"; - - // TODO: Cache this regexp for certain depths. - // Create a regexp suitable for matching an li for a given stack depth - function regex_for_depth( depth ) { - - return new RegExp( - // m[1] = indent, m[2] = list_type - "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" + - // m[3] = cont - "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})" - ); - } - function expand_tab( input ) { - return input.replace( / {0,3}\t/g, " " ); - } - - // Add inline content `inline` to `li`. inline comes from processInline - // so is an array of content - function add(li, loose, inline, nl) { - if (loose) { - li.push( [ "para" ].concat(inline) ); - return; - } - // Hmmm, should this be any block level element or just paras? - var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para" - ? li[li.length -1] - : li; - - // If there is already some content in this list, add the new line in - if (nl && li.length > 1) inline.unshift(nl); - - for (var i=0; i < inline.length; i++) { - var what = inline[i], - is_str = typeof what == "string"; - if (is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) { - add_to[ add_to.length-1 ] += what; - } - else { - add_to.push( what ); - } - } - } - - // contained means have an indent greater than the current one. On - // *every* line in the block - function get_contained_blocks( depth, blocks ) { - - var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ), - replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"), - ret = []; - - while ( blocks.length > 0 ) { - if ( re.exec( blocks[0] ) ) { - var b = blocks.shift(), - // Now remove that indent - x = b.replace( replace, ""); - - ret.push( mk_block( x, b.trailing, b.lineNumber ) ); - } - break; - } - return ret; - } - - // passed to stack.forEach to turn list items up the stack into paras - function paragraphify(s, i, stack) { - var list = s.list; - var last_li = list[list.length-1]; - - if (last_li[1] instanceof Array && last_li[1][0] == "para") { - return; - } - if (i+1 == stack.length) { - // Last stack frame - // Keep the same array, but replace the contents - last_li.push( ["para"].concat( last_li.splice(1) ) ); - } - else { - var sublist = last_li.pop(); - last_li.push( ["para"].concat( last_li.splice(1) ), sublist ); - } - } - - // The matcher function - return function( block, next ) { - var m = block.match( is_list_re ); - if ( !m ) return undefined; - - function make_list( m ) { - var list = bullet_list.exec( m[2] ) - ? ["bulletlist"] - : ["numberlist"]; - - stack.push( { list: list, indent: m[1] } ); - return list; - } - - - var stack = [], // Stack of lists for nesting. - list = make_list( m ), - last_li, - loose = false, - ret = [ stack[0].list ], - i; - - // Loop to search over block looking for inner block elements and loose lists - loose_search: - while( true ) { - // Split into lines preserving new lines at end of line - var lines = block.split( /(?=\n)/ ); - - // We have to grab all lines for a li and call processInline on them - // once as there are some inline things that can span lines. - var li_accumulate = ""; - - // Loop over the lines in this block looking for tight lists. - tight_search: - for (var line_no=0; line_no < lines.length; line_no++) { - var nl = "", - l = lines[line_no].replace(/^\n/, function(n) { nl = n; return ""; }); - - // TODO: really should cache this - var line_re = regex_for_depth( stack.length ); - - m = l.match( line_re ); - //print( "line:", uneval(l), "\nline match:", uneval(m) ); - - // We have a list item - if ( m[1] !== undefined ) { - // Process the previous list item, if any - if ( li_accumulate.length ) { - add( last_li, loose, this.processInline( li_accumulate ), nl ); - // Loose mode will have been dealt with. Reset it - loose = false; - li_accumulate = ""; - } - - m[1] = expand_tab( m[1] ); - var wanted_depth = Math.floor(m[1].length/4)+1; - //print( "want:", wanted_depth, "stack:", stack.length); - if ( wanted_depth > stack.length ) { - // Deep enough for a nested list outright - //print ( "new nested list" ); - list = make_list( m ); - last_li.push( list ); - last_li = list[1] = [ "listitem" ]; - } - else { - // We aren't deep enough to be strictly a new level. This is - // where Md.pl goes nuts. If the indent matches a level in the - // stack, put it there, else put it one deeper then the - // wanted_depth deserves. - var found = false; - for (i = 0; i < stack.length; i++) { - if ( stack[ i ].indent != m[1] ) continue; - list = stack[ i ].list; - stack.splice( i+1 ); - found = true; - break; - } - - if (!found) { - //print("not found. l:", uneval(l)); - wanted_depth++; - if (wanted_depth <= stack.length) { - stack.splice(wanted_depth); - //print("Desired depth now", wanted_depth, "stack:", stack.length); - list = stack[wanted_depth-1].list; - //print("list:", uneval(list) ); - } - else { - //print ("made new stack for messy indent"); - list = make_list(m); - last_li.push(list); - } - } - - //print( uneval(list), "last", list === stack[stack.length-1].list ); - last_li = [ "listitem" ]; - list.push(last_li); - } // end depth of shenegains - nl = ""; - } - - // Add content - if (l.length > m[0].length) { - li_accumulate += nl + l.substr( m[0].length ); - } - } // tight_search - - if ( li_accumulate.length ) { - add( last_li, loose, this.processInline( li_accumulate ), nl ); - // Loose mode will have been dealt with. Reset it - loose = false; - li_accumulate = ""; - } - - // Look at the next block - we might have a loose list. Or an extra - // paragraph for the current li - var contained = get_contained_blocks( stack.length, next ); - - // Deal with code blocks or properly nested lists - if (contained.length > 0) { - // Make sure all listitems up the stack are paragraphs - forEach( stack, paragraphify, this); - - last_li.push.apply( last_li, this.toTree( contained, [] ) ); - } - - var next_block = next[0] && next[0].valueOf() || ""; - - if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) { - block = next.shift(); - - // Check for an HR following a list: features/lists/hr_abutting - var hr = this.dialect.block.horizRule( block, next ); - - if (hr) { - ret.push.apply(ret, hr); - break; - } - - // Make sure all listitems up the stack are paragraphs - forEach( stack, paragraphify, this); - - loose = true; - continue loose_search; - } - break; - } // loose_search - - return ret; - }; - })(), - - blockquote: function blockquote( block, next ) { - if ( !block.match( /^>/m ) ) - return undefined; - - var jsonml = []; - - // separate out the leading abutting block, if any - if ( block[ 0 ] != ">" ) { - var lines = block.split( /\n/ ), - prev = []; - - // keep shifting lines until you find a crotchet - while ( lines.length && lines[ 0 ][ 0 ] != ">" ) { - prev.push( lines.shift() ); - } - - // reassemble! - block = lines.join( "\n" ); - jsonml.push.apply( jsonml, this.processBlock( prev.join( "\n" ), [] ) ); - } - - // if the next block is also a blockquote merge it in - while ( next.length && next[ 0 ][ 0 ] == ">" ) { - var b = next.shift(); - block = new String(block + block.trailing + b); - block.trailing = b.trailing; - } - - // Strip off the leading "> " and re-process as a block. - var input = block.replace( /^> ?/gm, '' ), - old_tree = this.tree; - jsonml.push( this.toTree( input, [ "blockquote" ] ) ); - - return jsonml; - }, - - referenceDefn: function referenceDefn( block, next) { - var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/; - // interesting matches are [ , ref_id, url, , title, title ] - - if ( !block.match(re) ) - return undefined; - - // make an attribute node if it doesn't exist - if ( !extract_attr( this.tree ) ) { - this.tree.splice( 1, 0, {} ); - } - - var attrs = extract_attr( this.tree ); - - // make a references hash if it doesn't exist - if ( attrs.references === undefined ) { - attrs.references = {}; - } - - var b = this.loop_re_over_block(re, block, function( m ) { - - if ( m[2] && m[2][0] == '<' && m[2][m[2].length-1] == '>' ) - m[2] = m[2].substring( 1, m[2].length - 1 ); - - var ref = attrs.references[ m[1].toLowerCase() ] = { - href: m[2] - }; - - if (m[4] !== undefined) - ref.title = m[4]; - else if (m[5] !== undefined) - ref.title = m[5]; - - } ); - - if (b.length) - next.unshift( mk_block( b, block.trailing ) ); - - return []; - }, - - para: function para( block, next ) { - // everything's a para! - return [ ["para"].concat( this.processInline( block ) ) ]; - } - } -}; - -Markdown.dialects.Gruber.inline = { - - __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) { - var m, - res, - lastIndex = 0; - - patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__; - var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" ); - - m = re.exec( text ); - if (!m) { - // Just boring text - return [ text.length, text ]; - } - else if ( m[1] ) { - // Some un-interesting text matched. Return that first - return [ m[1].length, m[1] ]; - } - - var res; - if ( m[2] in this.dialect.inline ) { - res = this.dialect.inline[ m[2] ].call( - this, - text.substr( m.index ), m, previous_nodes || [] ); - } - // Default for now to make dev easier. just slurp special and output it. - res = res || [ m[2].length, m[2] ]; - return res; - }, - - __call__: function inline( text, patterns ) { - - var out = [], - res; - - function add(x) { - //D:self.debug(" adding output", uneval(x)); - if (typeof x == "string" && typeof out[out.length-1] == "string") - out[ out.length-1 ] += x; - else - out.push(x); - } - - while ( text.length > 0 ) { - res = this.dialect.inline.__oneElement__.call(this, text, patterns, out ); - text = text.substr( res.shift() ); - forEach(res, add ) - } - - return out; - }, - - // These characters are intersting elsewhere, so have rules for them so that - // chunks of plain text blocks don't include them - "]": function () {}, - "}": function () {}, - - "\\": function escaped( text ) { - // [ length of input processed, node/children to add... ] - // Only esacape: \ ` * _ { } [ ] ( ) # * + - . ! - if ( text.match( /^\\[\\`\*_{}\[\]()#\+.!\-]/ ) ) - return [ 2, text[1] ]; - else - // Not an esacpe - return [ 1, "\\" ]; - }, - - "![": function image( text ) { - - // Unlike images, alt text is plain text only. no other elements are - // allowed in there - - // ![Alt text](/path/to/img.jpg "Optional title") - // 1 2 3 4 <--- captures - var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*(\S*)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ ); - - if ( m ) { - if ( m[2] && m[2][0] == '<' && m[2][m[2].length-1] == '>' ) - m[2] = m[2].substring( 1, m[2].length - 1 ); - - m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0]; - - var attrs = { alt: m[1], href: m[2] || "" }; - if ( m[4] !== undefined) - attrs.title = m[4]; - - return [ m[0].length, [ "img", attrs ] ]; - } - - // ![Alt text][id] - m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ ); - - if ( m ) { - // We can't check if the reference is known here as it likely wont be - // found till after. Check it in md tree->hmtl tree conversion - return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), original: m[0] } ] ]; - } - - // Just consume the '![' - return [ 2, "![" ]; - }, - - "[": function link( text ) { - - var orig = String(text); - // Inline content is possible inside `link text` - var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), ']' ); - - // No closing ']' found. Just consume the [ - if ( !res ) return [ 1, '[' ]; - - var consumed = 1 + res[ 0 ], - children = res[ 1 ], - link, - attrs; - - // At this point the first [...] has been parsed. See what follows to find - // out which kind of link we are (reference or direct url) - text = text.substr( consumed ); - - // [link text](/path/to/img.jpg "Optional title") - // 1 2 3 <--- captures - // This will capture up to the last paren in the block. We then pull - // back based on if there a matching ones in the url - // ([here](/url/(test)) - // The parens have to be balanced - var m = text.match( /^\s*\([ \t]*(\S+)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ ); - if ( m ) { - var url = m[1]; - consumed += m[0].length; - - if ( url && url[0] == '<' && url[url.length-1] == '>' ) - url = url.substring( 1, url.length - 1 ); - - // If there is a title we don't have to worry about parens in the url - if ( !m[3] ) { - var open_parens = 1; // One open that isn't in the capture - for (var len = 0; len < url.length; len++) { - switch ( url[len] ) { - case '(': - open_parens++; - break; - case ')': - if ( --open_parens == 0) { - consumed -= url.length - len; - url = url.substring(0, len); - } - break; - } - } - } - - // Process escapes only - url = this.dialect.inline.__call__.call( this, url, /\\/ )[0]; - - attrs = { href: url || "" }; - if ( m[3] !== undefined) - attrs.title = m[3]; - - link = [ "link", attrs ].concat( children ); - return [ consumed, link ]; - } - - // [Alt text][id] - // [Alt text] [id] - m = text.match( /^\s*\[(.*?)\]/ ); - - if ( m ) { - - consumed += m[ 0 ].length; - - // [links][] uses links as its reference - attrs = { ref: ( m[ 1 ] || String(children) ).toLowerCase(), original: orig.substr( 0, consumed ) }; - - link = [ "link_ref", attrs ].concat( children ); - - // We can't check if the reference is known here as it likely wont be - // found till after. Check it in md tree->hmtl tree conversion. - // Store the original so that conversion can revert if the ref isn't found. - return [ consumed, link ]; - } - - // [id] - // Only if id is plain (no formatting.) - if ( children.length == 1 && typeof children[0] == "string" ) { - - attrs = { ref: children[0].toLowerCase(), original: orig.substr( 0, consumed ) }; - link = [ "link_ref", attrs, children[0] ]; - return [ consumed, link ]; - } - - // Just consume the '[' - return [ 1, "[" ]; - }, - - - "<": function autoLink( text ) { - var m; - - if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) { - if ( m[3] ) { - return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ]; - - } - else if ( m[2] == "mailto" ) { - return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ]; - } - else - return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ]; - } - - return [ 1, "<" ]; - }, - - "`": function inlineCode( text ) { - // Inline code block. as many backticks as you like to start it - // Always skip over the opening ticks. - var m = text.match( /(`+)(([\s\S]*?)\1)/ ); - - if ( m && m[2] ) - return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ]; - else { - // TODO: No matching end code found - warn! - return [ 1, "`" ]; - } - }, - - " \n": function lineBreak( text ) { - return [ 3, [ "linebreak" ] ]; - } - -}; - -// Meta Helper/generator method for em and strong handling -function strong_em( tag, md ) { - - var state_slot = tag + "_state", - other_slot = tag == "strong" ? "em_state" : "strong_state"; - - function CloseTag(len) { - this.len_after = len; - this.name = "close_" + md; - } - - return function ( text, orig_match ) { - - if (this[state_slot][0] == md) { - // Most recent em is of this type - //D:this.debug("closing", md); - this[state_slot].shift(); - - // "Consume" everything to go back to the recrusion in the else-block below - return[ text.length, new CloseTag(text.length-md.length) ]; - } - else { - // Store a clone of the em/strong states - var other = this[other_slot].slice(), - state = this[state_slot].slice(); - - this[state_slot].unshift(md); - - //D:this.debug_indent += " "; - - // Recurse - var res = this.processInline( text.substr( md.length ) ); - //D:this.debug_indent = this.debug_indent.substr(2); - - var last = res[res.length - 1]; - - //D:this.debug("processInline from", tag + ": ", uneval( res ) ); - - var check = this[state_slot].shift(); - if (last instanceof CloseTag) { - res.pop(); - // We matched! Huzzah. - var consumed = text.length - last.len_after; - return [ consumed, [ tag ].concat(res) ]; - } - else { - // Restore the state of the other kind. We might have mistakenly closed it. - this[other_slot] = other; - this[state_slot] = state; - - // We can't reuse the processed result as it could have wrong parsing contexts in it. - return [ md.length, md ]; - } - } - }; // End returned function -} - -Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**"); -Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__"); -Markdown.dialects.Gruber.inline["*"] = strong_em("em", "*"); -Markdown.dialects.Gruber.inline["_"] = strong_em("em", "_"); - - -// Build default order from insertion order. -Markdown.buildBlockOrder = function(d) { - var ord = []; - for ( var i in d ) { - if ( i == "__order__" || i == "__call__" ) continue; - ord.push( i ); - } - d.__order__ = ord; -}; - -// Build patterns for inline matcher -Markdown.buildInlinePatterns = function(d) { - var patterns = []; - - for ( var i in d ) { - // __foo__ is reserved and not a pattern - if ( i.match( /^__.*__$/) ) continue; - var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" ) - .replace( /\n/, "\\n" ); - patterns.push( i.length == 1 ? l : "(?:" + l + ")" ); - } - - patterns = patterns.join("|"); - d.__patterns__ = patterns; - //print("patterns:", uneval( patterns ) ); - - var fn = d.__call__; - d.__call__ = function(text, pattern) { - if (pattern != undefined) { - return fn.call(this, text, pattern); - } - else - { - return fn.call(this, text, patterns); - } - }; -}; - -Markdown.DialectHelpers = {}; -Markdown.DialectHelpers.inline_until_char = function( text, want ) { - var consumed = 0, - nodes = []; - - while ( true ) { - if ( text[ consumed ] == want ) { - // Found the character we were looking for - consumed++; - return [ consumed, nodes ]; - } - - if ( consumed >= text.length ) { - // No closing char found. Abort. - return null; - } - - var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) ); - consumed += res[ 0 ]; - // Add any returned nodes. - nodes.push.apply( nodes, res.slice( 1 ) ); - } -} - -// Helper function to make sub-classing a dialect easier -Markdown.subclassDialect = function( d ) { - function Block() {} - Block.prototype = d.block; - function Inline() {} - Inline.prototype = d.inline; - - return { block: new Block(), inline: new Inline() }; -}; - -Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block ); -Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline ); - -Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber ); - -Markdown.dialects.Maruku.processMetaHash = function processMetaHash( meta_string ) { - var meta = split_meta_hash( meta_string ), - attr = {}; - - for ( var i = 0; i < meta.length; ++i ) { - // id: #foo - if ( /^#/.test( meta[ i ] ) ) { - attr.id = meta[ i ].substring( 1 ); - } - // class: .foo - else if ( /^\./.test( meta[ i ] ) ) { - // if class already exists, append the new one - if ( attr['class'] ) { - attr['class'] = attr['class'] + meta[ i ].replace( /./, " " ); - } - else { - attr['class'] = meta[ i ].substring( 1 ); - } - } - // attribute: foo=bar - else if ( /\=/.test( meta[ i ] ) ) { - var s = meta[ i ].split( /\=/ ); - attr[ s[ 0 ] ] = s[ 1 ]; - } - } - - return attr; -} - -function split_meta_hash( meta_string ) { - var meta = meta_string.split( "" ), - parts = [ "" ], - in_quotes = false; - - while ( meta.length ) { - var letter = meta.shift(); - switch ( letter ) { - case " " : - // if we're in a quoted section, keep it - if ( in_quotes ) { - parts[ parts.length - 1 ] += letter; - } - // otherwise make a new part - else { - parts.push( "" ); - } - break; - case "'" : - case '"' : - // reverse the quotes and move straight on - in_quotes = !in_quotes; - break; - case "\\" : - // shift off the next letter to be used straight away. - // it was escaped so we'll keep it whatever it is - letter = meta.shift(); - default : - parts[ parts.length - 1 ] += letter; - break; - } - } - - return parts; -} - -Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) { - // we're only interested in the first block - if ( block.lineNumber > 1 ) return undefined; - - // document_meta blocks consist of one or more lines of `Key: Value\n` - if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined; - - // make an attribute node if it doesn't exist - if ( !extract_attr( this.tree ) ) { - this.tree.splice( 1, 0, {} ); - } - - var pairs = block.split( /\n/ ); - for ( p in pairs ) { - var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ), - key = m[ 1 ].toLowerCase(), - value = m[ 2 ]; - - this.tree[ 1 ][ key ] = value; - } - - // document_meta produces no content! - return []; -}; - -Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) { - // check if the last line of the block is an meta hash - var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ ); - if ( !m ) return undefined; - - // process the meta hash - var attr = this.dialect.processMetaHash( m[ 2 ] ); - - var hash; - - // if we matched ^ then we need to apply meta to the previous block - if ( m[ 1 ] === "" ) { - var node = this.tree[ this.tree.length - 1 ]; - hash = extract_attr( node ); - - // if the node is a string (rather than JsonML), bail - if ( typeof node === "string" ) return undefined; - - // create the attribute hash if it doesn't exist - if ( !hash ) { - hash = {}; - node.splice( 1, 0, hash ); - } - - // add the attributes in - for ( a in attr ) { - hash[ a ] = attr[ a ]; - } - - // return nothing so the meta hash is removed - return []; - } - - // pull the meta hash off the block and process what's left - var b = block.replace( /\n.*$/, "" ), - result = this.processBlock( b, [] ); - - // get or make the attributes hash - hash = extract_attr( result[ 0 ] ); - if ( !hash ) { - hash = {}; - result[ 0 ].splice( 1, 0, hash ); - } - - // attach the attributes to the block - for ( a in attr ) { - hash[ a ] = attr[ a ]; - } - - return result; -}; - -Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) { - // one or more terms followed by one or more definitions, in a single block - var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/, - list = [ "dl" ], - i; - - // see if we're dealing with a tight or loose block - if ( ( m = block.match( tight ) ) ) { - // pull subsequent tight DL blocks out of `next` - var blocks = [ block ]; - while ( next.length && tight.exec( next[ 0 ] ) ) { - blocks.push( next.shift() ); - } - - for ( var b = 0; b < blocks.length; ++b ) { - var m = blocks[ b ].match( tight ), - terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ), - defns = m[ 2 ].split( /\n:\s+/ ); - - // print( uneval( m ) ); - - for ( i = 0; i < terms.length; ++i ) { - list.push( [ "dt", terms[ i ] ] ); - } - - for ( i = 0; i < defns.length; ++i ) { - // run inline processing over the definition - list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) ); - } - } - } - else { - return undefined; - } - - return [ list ]; -}; - -Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) { - if ( !out.length ) { - return [ 2, "{:" ]; - } - - // get the preceeding element - var before = out[ out.length - 1 ]; - - if ( typeof before === "string" ) { - return [ 2, "{:" ]; - } - - // match a meta hash - var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ ); - - // no match, false alarm - if ( !m ) { - return [ 2, "{:" ]; - } - - // attach the attributes to the preceeding element - var meta = this.dialect.processMetaHash( m[ 1 ] ), - attr = extract_attr( before ); - - if ( !attr ) { - attr = {}; - before.splice( 1, 0, attr ); - } - - for ( var k in meta ) { - attr[ k ] = meta[ k ]; - } - - // cut out the string and replace it with nothing - return [ m[ 0 ].length, "" ]; -}; - -Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block ); -Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline ); - -var isArray = Array.isArray || function(obj) { - return Object.prototype.toString.call(obj) == '[object Array]'; -}; - -var forEach; -// Don't mess with Array.prototype. Its not friendly -if ( Array.prototype.forEach ) { - forEach = function( arr, cb, thisp ) { - return arr.forEach( cb, thisp ); - }; -} -else { - forEach = function(arr, cb, thisp) { - for (var i = 0; i < arr.length; i++) { - cb.call(thisp || arr, arr[i], i, arr); - } - } -} - -function extract_attr( jsonml ) { - return isArray(jsonml) - && jsonml.length > 1 - && typeof jsonml[ 1 ] === "object" - && !( isArray(jsonml[ 1 ]) ) - ? jsonml[ 1 ] - : undefined; -} - - - -/** - * renderJsonML( jsonml[, options] ) -> String - * - jsonml (Array): JsonML array to render to XML - * - options (Object): options - * - * Converts the given JsonML into well-formed XML. - * - * The options currently understood are: - * - * - root (Boolean): wether or not the root node should be included in the - * output, or just its children. The default `false` is to not include the - * root itself. - */ -expose.renderJsonML = function( jsonml, options ) { - options = options || {}; - // include the root element in the rendered output? - options.root = options.root || false; - - var content = []; - - if ( options.root ) { - content.push( render_tree( jsonml ) ); - } - else { - jsonml.shift(); // get rid of the tag - if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) { - jsonml.shift(); // get rid of the attributes - } - - while ( jsonml.length ) { - content.push( render_tree( jsonml.shift() ) ); - } - } - - return content.join( "\n\n" ); -}; - -function escapeHTML( text ) { - return text.replace( /&/g, "&" ) - .replace( //g, ">" ) - .replace( /"/g, """ ) - .replace( /'/g, "'" ); -} - -function render_tree( jsonml ) { - // basic case - if ( typeof jsonml === "string" ) { - return escapeHTML( jsonml ); - } - - var tag = jsonml.shift(), - attributes = {}, - content = []; - - if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) { - attributes = jsonml.shift(); - } - - while ( jsonml.length ) { - content.push( arguments.callee( jsonml.shift() ) ); - } - - var tag_attrs = ""; - for ( var a in attributes ) { - tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"'; - } - - // be careful about adding whitespace here for inline elements - if ( tag == "img" || tag == "br" || tag == "hr" ) { - return "<"+ tag + tag_attrs + "/>"; - } - else { - return "<"+ tag + tag_attrs + ">" + content.join( "" ) + ""; - } -} - -function convert_tree_to_html( tree, references, options ) { - var i; - options = options || {}; - - // shallow clone - var jsonml = tree.slice( 0 ); - - if (typeof options.preprocessTreeNode === "function") { - jsonml = options.preprocessTreeNode(jsonml, references); - } - - // Clone attributes if they exist - var attrs = extract_attr( jsonml ); - if ( attrs ) { - jsonml[ 1 ] = {}; - for ( i in attrs ) { - jsonml[ 1 ][ i ] = attrs[ i ]; - } - attrs = jsonml[ 1 ]; - } - - // basic case - if ( typeof jsonml === "string" ) { - return jsonml; - } - - // convert this node - switch ( jsonml[ 0 ] ) { - case "header": - jsonml[ 0 ] = "h" + jsonml[ 1 ].level; - delete jsonml[ 1 ].level; - break; - case "bulletlist": - jsonml[ 0 ] = "ul"; - break; - case "numberlist": - jsonml[ 0 ] = "ol"; - break; - case "listitem": - jsonml[ 0 ] = "li"; - break; - case "para": - jsonml[ 0 ] = "p"; - break; - case "markdown": - jsonml[ 0 ] = "html"; - if ( attrs ) delete attrs.references; - break; - case "code_block": - jsonml[ 0 ] = "pre"; - i = attrs ? 2 : 1; - var code = [ "code" ]; - code.push.apply( code, jsonml.splice( i ) ); - jsonml[ i ] = code; - break; - case "inlinecode": - jsonml[ 0 ] = "code"; - break; - case "img": - jsonml[ 1 ].src = jsonml[ 1 ].href; - delete jsonml[ 1 ].href; - break; - case "linebreak": - jsonml[ 0 ] = "br"; - break; - case "link": - jsonml[ 0 ] = "a"; - break; - case "link_ref": - jsonml[ 0 ] = "a"; - - // grab this ref and clean up the attribute node - var ref = Object.prototype.hasOwnProperty.call(references, attrs.ref) && references[ attrs.ref ]; - - // if the reference exists, make the link - if ( ref ) { - delete attrs.ref; - - // add in the href and title, if present - attrs.href = ref.href; - if ( ref.title ) { - attrs.title = ref.title; - } - - // get rid of the unneeded original text - delete attrs.original; - } - // the reference doesn't exist, so revert to plain text - else { - return attrs.original; - } - break; - case "img_ref": - jsonml[ 0 ] = "img"; - - // grab this ref and clean up the attribute node - var ref = Object.prototype.hasOwnProperty.call(references, attrs.ref) && references[ attrs.ref ]; - - // if the reference exists, make the link - if ( ref ) { - delete attrs.ref; - - // add in the href and title, if present - attrs.src = ref.href; - if ( ref.title ) { - attrs.title = ref.title; - } - - // get rid of the unneeded original text - delete attrs.original; - } - // the reference doesn't exist, so revert to plain text - else { - return attrs.original; - } - break; - } - - // convert all the children - i = 1; - - // deal with the attribute node, if it exists - if ( attrs ) { - // if there are keys, skip over it - for ( var key in jsonml[ 1 ] ) { - i = 2; - } - // if there aren't, remove it - if ( i === 1 ) { - jsonml.splice( i, 1 ); - } - } - - for ( ; i < jsonml.length; ++i ) { - jsonml[ i ] = arguments.callee( jsonml[ i ], references, options ); - } - - return jsonml; -} - - -// merges adjacent text nodes into a single node -function merge_text_nodes( jsonml ) { - // skip the tag name and attribute hash - var i = extract_attr( jsonml ) ? 2 : 1; - - while ( i < jsonml.length ) { - // if it's a string check the next item too - if ( typeof jsonml[ i ] === "string" ) { - if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) { - // merge the second string into the first and remove it - jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ]; - } - else { - ++i; - } - } - // if it's not a string recurse - else { - arguments.callee( jsonml[ i ] ); - ++i; - } - } -} - -} )( (function() { - if ( typeof exports === "undefined" ) { - window.markdown = {}; - return window.markdown; - } - else { - return exports; - } -} )() ); diff --git a/rsc/scripts/jsdoc/node_modules/markdown/package.json b/rsc/scripts/jsdoc/node_modules/markdown/package.json deleted file mode 100644 index 0db4dd0a..00000000 --- a/rsc/scripts/jsdoc/node_modules/markdown/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "markdown", - "version": "0.4.0", - "description": "A sensible Markdown parser for javascript", - "keywords": [ - "markdown", - "text processing", - "ast" - ], - "maintainers": [ - { - "name": "Dominic Baggott", - "email": "dominic.baggott@gmail.com", - "url": "http://evilstreak.co.uk" - }, - { - "name": "Ash Berlin", - "email": "ash_markdownjs@firemirror.com", - "url": "http://ashberlin.com" - } - ], - "contributors": [ - { - "name": "Dominic Baggott", - "email": "dominic.baggott@gmail.com", - "url": "http://evilstreak.co.uk" - }, - { - "name": "Ash Berlin", - "email": "ash_markdownjs@firemirror.com", - "url": "http://ashberlin.com" - } - ], - "bugs": { - "url": "http://github.com/evilstreak/markdown-js/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/mit-license.php" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/evilstreak/markdown-js.git" - }, - "main": "./lib/index.js", - "bin": { - "md2html": "./bin/md2html.js" - }, - "dependencies": { - "nopt": "1" - }, - "devDependencies": { - "tap": "0" - }, - "scripts": { - "test": "tap test/*.t.js" - }, - "readme": "markdown-js\n===========\n\nYet another markdown parser, this time for JavaScript. There's a few\noptions that precede this project but they all treat markdown to HTML\nconversion as a single step process. You pass markdown in and get HTML\nout, end of story. We had some pretty particular views on how the\nprocess should actually look, which include:\n\n * producing well-formed HTML. This means that em and strong nesting is\n important, as is the ability to output as both HTML and XHTML\n\n * having an intermediate representation to allow processing of parsed\n data (we in fact have two, both [JsonML]: a markdown tree and an\n HTML tree)\n\n * being easily extensible to add new dialects without having to\n rewrite the entire parsing mechanics\n\n * having a good test suite. The only test suites we could find tested\n massive blocks of input, and passing depended on outputting the HTML\n with exactly the same whitespace as the original implementation\n\n[JsonML]: http://jsonml.org/ \"JSON Markup Language\"\n\n## Installation\n\nJust the `markdown` library:\n\n npm install markdown\n\nAlso install `md2html` to `/usr/local/bin` (or wherever)\n\n npm install -g markdown\n\n## Usage\n\nThe simple way to use it with CommonJS is:\n\n var input = \"# Heading\\n\\nParagraph\";\n var output = require( \"markdown\" ).markdown.toHTML( input );\n print( output );\n\nIf you want more control check out the documentation in\n[lib/markdown.js] which details all the methods and parameters\navailable (including examples!). One day we'll get the docs generated\nand hosted somewhere for nicer browsing.\n\nIt also works in a browser; here is a complete example:\n\n \n \n \n \n
    \n \n \n \n \n\n### md2html\n\n md2html /path/to/doc.md > /path/to/doc.html\n\n[lib/markdown.js]: http://github.com/evilstreak/markdown-js/blob/master/lib/markdown.js\n\n## Intermediate Representation\n\nInternally the process to convert a chunk of markdown into a chunk of\nHTML has three steps:\n\n 1. Parse the markdown into a JsonML tree. Any references found in the\n parsing are stored in the attribute hash of the root node under the\n key `references`.\n\n 2. Convert the markdown tree into an HTML tree. Rename any nodes that\n need it (`bulletlist` to `ul` for example) and lookup any references\n used by links or images. Remove the references attribute once done.\n\n 3. Stringify the HTML tree being careful not to wreck whitespace where\n whitespace is important (surrounding inline elements for example).\n\nEach step of this process can be called individually if you need to do\nsome processing or modification of the data at an intermediate stage.\nFor example, you may want to grab a list of all URLs linked to in the\ndocument before rendering it to HTML which you could do by recursing\nthrough the HTML tree looking for `a` nodes.\n\n## Running tests\n\nTo run the tests under node you will need tap installed (it's listed as a\ndevDependencies so `npm install` from the checkout should be enough), then do\n\n $ ./node_modules/.bin/tap test/*.t.js\n\n## Contributing\n\nDo the usual github fork and pull request dance. Add yourself to the\ncontributors section of package.json too if you want to.\n\n## License\n\nReleased under the MIT license.\n", - "readmeFilename": "README.markdown", - "_id": "markdown@0.4.0", - "dist": { - "shasum": "6a5d7cb751c1d1e6adc374d40e9d358474b59a8e" - }, - "_resolved": "git://github.com/jsdoc3/markdown-js.git#fd27f4c979f3f71e82e1fe76ffe6415980b31f00", - "_from": "git://github.com/jsdoc3/markdown-js.git" -} diff --git a/rsc/scripts/jsdoc/node_modules/marked/LICENSE b/rsc/scripts/jsdoc/node_modules/marked/LICENSE deleted file mode 100644 index 11a61898..00000000 --- a/rsc/scripts/jsdoc/node_modules/marked/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011-2013, Christopher Jeffrey (https://github.com/chjj/) - -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. diff --git a/rsc/scripts/jsdoc/node_modules/marked/index.js b/rsc/scripts/jsdoc/node_modules/marked/index.js deleted file mode 100644 index a12f9056..00000000 --- a/rsc/scripts/jsdoc/node_modules/marked/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/marked'); diff --git a/rsc/scripts/jsdoc/node_modules/marked/lib/marked.js b/rsc/scripts/jsdoc/node_modules/marked/lib/marked.js deleted file mode 100644 index 1b76ab03..00000000 --- a/rsc/scripts/jsdoc/node_modules/marked/lib/marked.js +++ /dev/null @@ -1,1076 +0,0 @@ -/** - * marked - a markdown parser - * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed) - * https://github.com/chjj/marked - */ - -;(function() { - -/** - * Block-Level Grammar - */ - -var block = { - newline: /^\n+/, - code: /^( {4}[^\n]+\n*)+/, - fences: noop, - hr: /^( *[-*_]){3,} *(?:\n+|$)/, - heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, - nptable: noop, - lheading: /^([^\n]+)\n *(=|-){3,} *\n*/, - blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/, - list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, - html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, - def: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, - table: noop, - paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, - text: /^[^\n]+/ -}; - -block.bullet = /(?:[*+-]|\d+\.)/; -block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; -block.item = replace(block.item, 'gm') - (/bull/g, block.bullet) - (); - -block.list = replace(block.list) - (/bull/g, block.bullet) - ('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/) - (); - -block._tag = '(?!(?:' - + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' - + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' - + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b'; - -block.html = replace(block.html) - ('comment', //) - ('closed', /<(tag)[\s\S]+?<\/\1>/) - ('closing', /])*?>/) - (/tag/g, block._tag) - (); - -block.paragraph = replace(block.paragraph) - ('hr', block.hr) - ('heading', block.heading) - ('lheading', block.lheading) - ('blockquote', block.blockquote) - ('tag', '<' + block._tag) - ('def', block.def) - (); - -/** - * Normal Block Grammar - */ - -block.normal = merge({}, block); - -/** - * GFM Block Grammar - */ - -block.gfm = merge({}, block.normal, { - fences: /^ *(`{3,}|~{3,}) *(\w+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, - paragraph: /^/ -}); - -block.gfm.paragraph = replace(block.paragraph) - ('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|') - (); - -/** - * GFM + Tables Block Grammar - */ - -block.tables = merge({}, block.gfm, { - nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, - table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ -}); - -/** - * Block Lexer - */ - -function Lexer(options) { - this.tokens = []; - this.tokens.links = {}; - this.options = options || marked.defaults; - this.rules = block.normal; - - if (this.options.gfm) { - if (this.options.tables) { - this.rules = block.tables; - } else { - this.rules = block.gfm; - } - } -} - -/** - * Expose Block Rules - */ - -Lexer.rules = block; - -/** - * Static Lex Method - */ - -Lexer.lex = function(src, options) { - var lexer = new Lexer(options); - return lexer.lex(src); -}; - -/** - * Preprocessing - */ - -Lexer.prototype.lex = function(src) { - src = src - .replace(/\r\n|\r/g, '\n') - .replace(/\t/g, ' ') - .replace(/\u00a0/g, ' ') - .replace(/\u2424/g, '\n'); - - return this.token(src, true); -}; - -/** - * Lexing - */ - -Lexer.prototype.token = function(src, top) { - var src = src.replace(/^ +$/gm, '') - , next - , loose - , cap - , bull - , b - , item - , space - , i - , l; - - while (src) { - // newline - if (cap = this.rules.newline.exec(src)) { - src = src.substring(cap[0].length); - if (cap[0].length > 1) { - this.tokens.push({ - type: 'space' - }); - } - } - - // code - if (cap = this.rules.code.exec(src)) { - src = src.substring(cap[0].length); - cap = cap[0].replace(/^ {4}/gm, ''); - this.tokens.push({ - type: 'code', - text: !this.options.pedantic - ? cap.replace(/\n+$/, '') - : cap - }); - continue; - } - - // fences (gfm) - if (cap = this.rules.fences.exec(src)) { - src = src.substring(cap[0].length); - this.tokens.push({ - type: 'code', - lang: cap[2], - text: cap[3] - }); - continue; - } - - // heading - if (cap = this.rules.heading.exec(src)) { - src = src.substring(cap[0].length); - this.tokens.push({ - type: 'heading', - depth: cap[1].length, - text: cap[2] - }); - continue; - } - - // table no leading pipe (gfm) - if (top && (cap = this.rules.nptable.exec(src))) { - src = src.substring(cap[0].length); - - item = { - type: 'table', - header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), - align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3].replace(/\n$/, '').split('\n') - }; - - for (i = 0; i < item.align.length; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; - } - } - - for (i = 0; i < item.cells.length; i++) { - item.cells[i] = item.cells[i].split(/ *\| */); - } - - this.tokens.push(item); - - continue; - } - - // lheading - if (cap = this.rules.lheading.exec(src)) { - src = src.substring(cap[0].length); - this.tokens.push({ - type: 'heading', - depth: cap[2] === '=' ? 1 : 2, - text: cap[1] - }); - continue; - } - - // hr - if (cap = this.rules.hr.exec(src)) { - src = src.substring(cap[0].length); - this.tokens.push({ - type: 'hr' - }); - continue; - } - - // blockquote - if (cap = this.rules.blockquote.exec(src)) { - src = src.substring(cap[0].length); - - this.tokens.push({ - type: 'blockquote_start' - }); - - cap = cap[0].replace(/^ *> ?/gm, ''); - - // Pass `top` to keep the current - // "toplevel" state. This is exactly - // how markdown.pl works. - this.token(cap, top); - - this.tokens.push({ - type: 'blockquote_end' - }); - - continue; - } - - // list - if (cap = this.rules.list.exec(src)) { - src = src.substring(cap[0].length); - - this.tokens.push({ - type: 'list_start', - ordered: isFinite(cap[2]) - }); - - // Get each top-level item. - cap = cap[0].match(this.rules.item); - - // Get bullet. - if (this.options.smartLists) { - bull = block.bullet.exec(cap[0])[0]; - } - - next = false; - l = cap.length; - i = 0; - - for (; i < l; i++) { - item = cap[i]; - - // Remove the list item's bullet - // so it is seen as the next token. - space = item.length; - item = item.replace(/^ *([*+-]|\d+\.) +/, ''); - - // Outdent whatever the - // list item contains. Hacky. - if (~item.indexOf('\n ')) { - space -= item.length; - item = !this.options.pedantic - ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') - : item.replace(/^ {1,4}/gm, ''); - } - - // Determine whether the next list item belongs here. - // Backpedal if it does not belong in this list. - if (this.options.smartLists && i !== l - 1) { - b = block.bullet.exec(cap[i+1])[0]; - if (bull !== b && !(bull[1] === '.' && b[1] === '.')) { - src = cap.slice(i + 1).join('\n') + src; - i = l - 1; - } - } - - // Determine whether item is loose or not. - // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ - // for discount behavior. - loose = next || /\n\n(?!\s*$)/.test(item); - if (i !== l - 1) { - next = item[item.length-1] === '\n'; - if (!loose) loose = next; - } - - this.tokens.push({ - type: loose - ? 'loose_item_start' - : 'list_item_start' - }); - - // Recurse. - this.token(item, false); - - this.tokens.push({ - type: 'list_item_end' - }); - } - - this.tokens.push({ - type: 'list_end' - }); - - continue; - } - - // html - if (cap = this.rules.html.exec(src)) { - src = src.substring(cap[0].length); - this.tokens.push({ - type: this.options.sanitize - ? 'paragraph' - : 'html', - pre: cap[1] === 'pre', - text: cap[0] - }); - continue; - } - - // def - if (top && (cap = this.rules.def.exec(src))) { - src = src.substring(cap[0].length); - this.tokens.links[cap[1].toLowerCase()] = { - href: cap[2], - title: cap[3] - }; - continue; - } - - // table (gfm) - if (top && (cap = this.rules.table.exec(src))) { - src = src.substring(cap[0].length); - - item = { - type: 'table', - header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), - align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') - }; - - for (i = 0; i < item.align.length; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; - } - } - - for (i = 0; i < item.cells.length; i++) { - item.cells[i] = item.cells[i] - .replace(/^ *\| *| *\| *$/g, '') - .split(/ *\| */); - } - - this.tokens.push(item); - - continue; - } - - // top-level paragraph - if (top && (cap = this.rules.paragraph.exec(src))) { - src = src.substring(cap[0].length); - this.tokens.push({ - type: 'paragraph', - text: cap[1][cap[1].length-1] === '\n' - ? cap[1].slice(0, -1) - : cap[1] - }); - continue; - } - - // text - if (cap = this.rules.text.exec(src)) { - // Top-level should never reach here. - src = src.substring(cap[0].length); - this.tokens.push({ - type: 'text', - text: cap[0] - }); - continue; - } - - if (src) { - throw new - Error('Infinite loop on byte: ' + src.charCodeAt(0)); - } - } - - return this.tokens; -}; - -/** - * Inline-Level Grammar - */ - -var inline = { - escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, - autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, - url: noop, - tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, - link: /^!?\[(inside)\]\(href\)/, - reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, - nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, - strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, - em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, - code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, - br: /^ {2,}\n(?!\s*$)/, - del: noop, - text: /^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/; - -inline.link = replace(inline.link) - ('inside', inline._inside) - ('href', inline._href) - (); - -inline.reflink = replace(inline.reflink) - ('inside', inline._inside) - (); - -/** - * Normal Inline Grammar - */ - -inline.normal = merge({}, inline); - -/** - * Pedantic Inline Grammar - */ - -inline.pedantic = merge({}, inline.normal, { - strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, - em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ -}); - -/** - * GFM Inline Grammar - */ - -inline.gfm = merge({}, inline.normal, { - escape: replace(inline.escape)('])', '~|])')(), - url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, - del: /^~~(?=\S)([\s\S]*?\S)~~/, - text: replace(inline.text) - (']|', '~]|') - ('|', '|https?://|') - () -}); - -/** - * GFM + Line Breaks Inline Grammar - */ - -inline.breaks = merge({}, inline.gfm, { - br: replace(inline.br)('{2,}', '*')(), - text: replace(inline.gfm.text)('{2,}', '*')() -}); - -/** - * Inline Lexer & Compiler - */ - -function InlineLexer(links, options) { - this.options = options || marked.defaults; - this.links = links; - this.rules = inline.normal; - - if (!this.links) { - throw new - Error('Tokens array requires a `links` property.'); - } - - if (this.options.gfm) { - if (this.options.breaks) { - this.rules = inline.breaks; - } else { - this.rules = inline.gfm; - } - } else if (this.options.pedantic) { - this.rules = inline.pedantic; - } -} - -/** - * Expose Inline Rules - */ - -InlineLexer.rules = inline; - -/** - * Static Lexing/Compiling Method - */ - -InlineLexer.output = function(src, links, options) { - var inline = new InlineLexer(links, options); - return inline.output(src); -}; - -/** - * Lexing/Compiling - */ - -InlineLexer.prototype.output = function(src) { - var out = '' - , link - , text - , href - , cap; - - while (src) { - // escape - if (cap = this.rules.escape.exec(src)) { - src = src.substring(cap[0].length); - out += cap[1]; - continue; - } - - // autolink - if (cap = this.rules.autolink.exec(src)) { - src = src.substring(cap[0].length); - if (cap[2] === '@') { - text = cap[1][6] === ':' - ? this.mangle(cap[1].substring(7)) - : this.mangle(cap[1]); - href = this.mangle('mailto:') + text; - } else { - text = escape(cap[1]); - href = text; - } - out += '
    ' - + text - + ''; - continue; - } - - // url (gfm) - if (cap = this.rules.url.exec(src)) { - src = src.substring(cap[0].length); - text = escape(cap[1]); - href = text; - out += '' - + text - + ''; - continue; - } - - // tag - if (cap = this.rules.tag.exec(src)) { - src = src.substring(cap[0].length); - out += this.options.sanitize - ? escape(cap[0]) - : cap[0]; - continue; - } - - // link - if (cap = this.rules.link.exec(src)) { - src = src.substring(cap[0].length); - out += this.outputLink(cap, { - href: cap[2], - title: cap[3] - }); - continue; - } - - // reflink, nolink - if ((cap = this.rules.reflink.exec(src)) - || (cap = this.rules.nolink.exec(src))) { - src = src.substring(cap[0].length); - link = (cap[2] || cap[1]).replace(/\s+/g, ' '); - link = this.links[link.toLowerCase()]; - if (!link || !link.href) { - out += cap[0][0]; - src = cap[0].substring(1) + src; - continue; - } - out += this.outputLink(cap, link); - continue; - } - - // strong - if (cap = this.rules.strong.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + this.output(cap[2] || cap[1]) - + ''; - continue; - } - - // em - if (cap = this.rules.em.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + this.output(cap[2] || cap[1]) - + ''; - continue; - } - - // code - if (cap = this.rules.code.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + escape(cap[2], true) - + ''; - continue; - } - - // br - if (cap = this.rules.br.exec(src)) { - src = src.substring(cap[0].length); - out += '
    '; - continue; - } - - // del (gfm) - if (cap = this.rules.del.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + this.output(cap[1]) - + ''; - continue; - } - - // text - if (cap = this.rules.text.exec(src)) { - src = src.substring(cap[0].length); - out += escape(cap[0]); - continue; - } - - if (src) { - throw new - Error('Infinite loop on byte: ' + src.charCodeAt(0)); - } - } - - return out; -}; - -/** - * Compile Link - */ - -InlineLexer.prototype.outputLink = function(cap, link) { - if (cap[0][0] !== '!') { - return '' - + this.output(cap[1]) - + ''; - } else { - return ''
-      + escape(cap[1])
-      + ''; - } -}; - -/** - * Mangle Links - */ - -InlineLexer.prototype.mangle = function(text) { - var out = '' - , l = text.length - , i = 0 - , ch; - - for (; i < l; i++) { - ch = text.charCodeAt(i); - if (Math.random() > 0.5) { - ch = 'x' + ch.toString(16); - } - out += '&#' + ch + ';'; - } - - return out; -}; - -/** - * Parsing & Compiling - */ - -function Parser(options) { - this.tokens = []; - this.token = null; - this.options = options || marked.defaults; -} - -/** - * Static Parse Method - */ - -Parser.parse = function(src, options) { - var parser = new Parser(options); - return parser.parse(src); -}; - -/** - * Parse Loop - */ - -Parser.prototype.parse = function(src) { - this.inline = new InlineLexer(src.links, this.options); - this.tokens = src.reverse(); - - var out = ''; - while (this.next()) { - out += this.tok(); - } - - return out; -}; - -/** - * Next Token - */ - -Parser.prototype.next = function() { - return this.token = this.tokens.pop(); -}; - -/** - * Preview Next Token - */ - -Parser.prototype.peek = function() { - return this.tokens[this.tokens.length-1] || 0; -}; - -/** - * Parse Text Tokens - */ - -Parser.prototype.parseText = function() { - var body = this.token.text; - - while (this.peek().type === 'text') { - body += '\n' + this.next().text; - } - - return this.inline.output(body); -}; - -/** - * Parse Current Token - */ - -Parser.prototype.tok = function() { - switch (this.token.type) { - case 'space': { - return ''; - } - case 'hr': { - return '
    \n'; - } - case 'heading': { - return '' - + this.inline.output(this.token.text) - + '\n'; - } - case 'code': { - if (this.options.highlight) { - var code = this.options.highlight(this.token.text, this.token.lang); - if (code != null && code !== this.token.text) { - this.token.escaped = true; - this.token.text = code; - } - } - - if (!this.token.escaped) { - this.token.text = escape(this.token.text, true); - } - - return '
    '
    -        + this.token.text
    -        + '
    \n'; - } - case 'table': { - var body = '' - , heading - , i - , row - , cell - , j; - - // header - body += '\n\n'; - for (i = 0; i < this.token.header.length; i++) { - heading = this.inline.output(this.token.header[i]); - body += this.token.align[i] - ? '' + heading + '\n' - : '' + heading + '\n'; - } - body += '\n\n'; - - // body - body += '\n' - for (i = 0; i < this.token.cells.length; i++) { - row = this.token.cells[i]; - body += '\n'; - for (j = 0; j < row.length; j++) { - cell = this.inline.output(row[j]); - body += this.token.align[j] - ? '' + cell + '\n' - : '' + cell + '\n'; - } - body += '\n'; - } - body += '\n'; - - return '\n' - + body - + '
    \n'; - } - case 'blockquote_start': { - var body = ''; - - while (this.next().type !== 'blockquote_end') { - body += this.tok(); - } - - return '
    \n' - + body - + '
    \n'; - } - case 'list_start': { - var type = this.token.ordered ? 'ol' : 'ul' - , body = ''; - - while (this.next().type !== 'list_end') { - body += this.tok(); - } - - return '<' - + type - + '>\n' - + body - + '\n'; - } - case 'list_item_start': { - var body = ''; - - while (this.next().type !== 'list_item_end') { - body += this.token.type === 'text' - ? this.parseText() - : this.tok(); - } - - return '
  • ' - + body - + '
  • \n'; - } - case 'loose_item_start': { - var body = ''; - - while (this.next().type !== 'list_item_end') { - body += this.tok(); - } - - return '
  • ' - + body - + '
  • \n'; - } - case 'html': { - return !this.token.pre && !this.options.pedantic - ? this.inline.output(this.token.text) - : this.token.text; - } - case 'paragraph': { - return '

    ' - + this.inline.output(this.token.text) - + '

    \n'; - } - case 'text': { - return '

    ' - + this.parseText() - + '

    \n'; - } - } -}; - -/** - * Helpers - */ - -function escape(html, encode) { - return html - .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); -} - -function replace(regex, opt) { - regex = regex.source; - opt = opt || ''; - return function self(name, val) { - if (!name) return new RegExp(regex, opt); - val = val.source || val; - val = val.replace(/(^|[^\[])\^/g, '$1'); - regex = regex.replace(name, val); - return self; - }; -} - -function noop() {} -noop.exec = noop; - -function merge(obj) { - var i = 1 - , target - , key; - - for (; i < arguments.length; i++) { - target = arguments[i]; - for (key in target) { - if (Object.prototype.hasOwnProperty.call(target, key)) { - obj[key] = target[key]; - } - } - } - - return obj; -} - -/** - * Marked - */ - -function marked(src, opt) { - try { - if (opt) opt = merge({}, marked.defaults, opt); - return Parser.parse(Lexer.lex(src, opt), opt); - } catch (e) { - e.message += '\nPlease report this to https://github.com/chjj/marked.'; - if ((opt || marked.defaults).silent) { - return '

    An error occured:

    '
    -        + escape(e.message + '', true)
    -        + '
    '; - } - throw e; - } -} - -/** - * Options - */ - -marked.options = -marked.setOptions = function(opt) { - merge(marked.defaults, opt); - return marked; -}; - -marked.defaults = { - gfm: true, - tables: true, - breaks: false, - pedantic: false, - sanitize: false, - smartLists: false, - silent: false, - highlight: null, - langPrefix: 'lang-' -}; - -/** - * Expose - */ - -marked.Parser = Parser; -marked.parser = Parser.parse; - -marked.Lexer = Lexer; -marked.lexer = Lexer.lex; - -marked.InlineLexer = InlineLexer; -marked.inlineLexer = InlineLexer.output; - -marked.parse = marked; - -if (typeof exports === 'object') { - module.exports = marked; -} else if (typeof define === 'function' && define.amd) { - define(function() { return marked; }); -} else { - this.marked = marked; -} - -}).call(function() { - return this || (typeof window !== 'undefined' ? window : global); -}()); diff --git a/rsc/scripts/jsdoc/node_modules/marked/package.json b/rsc/scripts/jsdoc/node_modules/marked/package.json deleted file mode 100644 index fce5b5f9..00000000 --- a/rsc/scripts/jsdoc/node_modules/marked/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "marked", - "description": "A markdown parser built for speed", - "author": { - "name": "Christopher Jeffrey" - }, - "version": "0.2.8", - "main": "./lib/marked.js", - "bin": { - "marked": "./bin/marked" - }, - "man": [ - "./man/marked.1" - ], - "preferGlobal": true, - "repository": { - "type": "git", - "url": "git://github.com/chjj/marked.git" - }, - "homepage": "https://github.com/chjj/marked", - "bugs": { - "url": "http://github.com/chjj/marked/issues" - }, - "keywords": [ - "markdown", - "markup", - "html" - ], - "tags": [ - "markdown", - "markup", - "html" - ], - "scripts": { - "test": "node test", - "bench": "node test --bench" - }, - "readme": "# marked\n\nA full-featured markdown parser and compiler, written in javascript.\nBuilt for speed.\n\n## Benchmarks\n\nnode v0.4.x\n\n``` bash\n$ node test --bench\nmarked completed in 12071ms.\nshowdown (reuse converter) completed in 27387ms.\nshowdown (new converter) completed in 75617ms.\nmarkdown-js completed in 70069ms.\n```\n\nnode v0.6.x\n\n``` bash\n$ node test --bench\nmarked completed in 6448ms.\nmarked (gfm) completed in 7357ms.\nmarked (pedantic) completed in 6092ms.\ndiscount completed in 7314ms.\nshowdown (reuse converter) completed in 16018ms.\nshowdown (new converter) completed in 18234ms.\nmarkdown-js completed in 24270ms.\n```\n\n__Marked is now faster than Discount, which is written in C.__\n\nFor those feeling skeptical: These benchmarks run the entire markdown test suite\n1000 times. The test suite tests every feature. It doesn't cater to specific\naspects.\n\n## Install\n\n``` bash\n$ npm install marked\n```\n\n## Another Javascript Markdown Parser\n\nThe point of marked was to create a markdown compiler where it was possible to\nfrequently parse huge chunks of markdown without having to worry about\ncaching the compiled output somehow...or blocking for an unnecesarily long time.\n\nmarked is very concise and still implements all markdown features. It is also\nnow fully compatible with the client-side.\n\nmarked more or less passes the official markdown test suite in its\nentirety. This is important because a surprising number of markdown compilers\ncannot pass more than a few tests. It was very difficult to get marked as\ncompliant as it is. It could have cut corners in several areas for the sake\nof performance, but did not in order to be exactly what you expect in terms\nof a markdown rendering. In fact, this is why marked could be considered at a\ndisadvantage in the benchmarks above.\n\nAlong with implementing every markdown feature, marked also implements\n[GFM features](http://github.github.com/github-flavored-markdown/).\n\n## Options\n\nmarked has a few different switches which change behavior.\n\n- __pedantic__: Conform to obscure parts of `markdown.pl` as much as possible.\n Don't fix any of the original markdown bugs or poor behavior.\n- __gfm__: Enable github flavored markdown (enabled by default).\n- __sanitize__: Sanitize the output. Ignore any HTML that has been input.\n- __highlight__: A callback to highlight code blocks.\n- __tables__: Enable GFM tables. This is enabled by default. (Requires the\n `gfm` option in order to be enabled).\n- __breaks__: Enable GFM line breaks. Disabled by default.\n- __smartLists__: Use smarter list behavior than the original markdown.\n Disabled by default. May eventually be default with the old behavior\n moved into `pedantic`.\n- __langPrefix__: Set the prefix for code block classes. Defaults to `lang-`.\n\n## Usage\n\n``` js\n// Set default options\nmarked.setOptions({\n gfm: true,\n tables: true,\n breaks: false,\n pedantic: false,\n sanitize: true,\n smartLists: true,\n langPrefix: 'language-',\n highlight: function(code, lang) {\n if (lang === 'js') {\n return highlighter.javascript(code);\n }\n return code;\n }\n});\nconsole.log(marked('i am using __markdown__.'));\n```\n\nYou also have direct access to the lexer and parser if you so desire.\n\n``` js\nvar tokens = marked.lexer(text, options);\nconsole.log(marked.parser(tokens));\n```\n\n``` js\nvar lexer = new marked.Lexer(options);\nvar tokens = lexer.lex(text);\nconsole.log(tokens);\nconsole.log(lexer.rules);\n```\n\n``` bash\n$ node\n> require('marked').lexer('> i am using marked.')\n[ { type: 'blockquote_start' },\n { type: 'paragraph',\n text: 'i am using marked.' },\n { type: 'blockquote_end' },\n links: {} ]\n```\n\n## CLI\n\n``` bash\n$ marked -o hello.html\nhello world\n^D\n$ cat hello.html\n

    hello world

    \n```\n\n## License\n\nCopyright (c) 2011-2013, Christopher Jeffrey. (MIT License)\n\nSee LICENSE for more info.\n", - "readmeFilename": "README.md", - "_id": "marked@0.2.8", - "dist": { - "shasum": "740103e3cd0e98050c99cd1cc2b8d823bf640aee" - }, - "_from": "marked@0.2.8", - "_resolved": "https://registry.npmjs.org/marked/-/marked-0.2.8.tgz" -} diff --git a/rsc/scripts/jsdoc/node_modules/taffydb/README.md b/rsc/scripts/jsdoc/node_modules/taffydb/README.md deleted file mode 100644 index 52d14a3a..00000000 --- a/rsc/scripts/jsdoc/node_modules/taffydb/README.md +++ /dev/null @@ -1 +0,0 @@ -See [http://taffydb.com](http://taffydb.com). \ No newline at end of file diff --git a/rsc/scripts/jsdoc/node_modules/taffydb/package.json b/rsc/scripts/jsdoc/node_modules/taffydb/package.json deleted file mode 100644 index 3cb561cf..00000000 --- a/rsc/scripts/jsdoc/node_modules/taffydb/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "taffydb", - "version": "2.6.2", - "description": "An open-source library that brings database features into your JavaScript applications.", - "main": "taffy.js", - "repository": { - "type": "git", - "url": "git://github.com/hegemonic/taffydb.git" - }, - "license": "BSD", - "readme": "See [http://taffydb.com](http://taffydb.com).", - "_id": "taffydb@2.6.2", - "dist": { - "shasum": "4ffeb4b49fd82c123fb5804606b0928f3e9e30b1" - }, - "_from": "taffydb@git://github.com/hegemonic/taffydb.git" -} diff --git a/rsc/scripts/jsdoc/node_modules/taffydb/taffy-test.html b/rsc/scripts/jsdoc/node_modules/taffydb/taffy-test.html deleted file mode 100644 index c4df78b4..00000000 --- a/rsc/scripts/jsdoc/node_modules/taffydb/taffy-test.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - taffy test - - - - - - -
    -Please open your javascript console to see test results -
    - - - - diff --git a/rsc/scripts/jsdoc/node_modules/taffydb/taffy.js b/rsc/scripts/jsdoc/node_modules/taffydb/taffy.js deleted file mode 100644 index b7ad88cd..00000000 --- a/rsc/scripts/jsdoc/node_modules/taffydb/taffy.js +++ /dev/null @@ -1,1973 +0,0 @@ -/* - - Software License Agreement (BSD License) - http://taffydb.com - Copyright (c) - All rights reserved. - - - Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following condition is met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - */ - -/*jslint browser : true, continue : true, - devel : true, indent : 2, maxerr : 500, - newcap : true, nomen : true, plusplus : true, - regexp : true, sloppy : true, vars : false, - white : true -*/ - -// BUILD 193d48d, modified by mmikowski to pass jslint - -// Setup TAFFY name space to return an object with methods -var TAFFY, exports, T; -(function () { - 'use strict'; - var - typeList, makeTest, idx, typeKey, - version, TC, idpad, cmax, - API, protectJSON, each, eachin, - isIndexable, returnFilter, runFilters, - numcharsplit, orderByCol, run - ; - - - if ( ! TAFFY ){ - // TC = Counter for Taffy DBs on page, used for unique IDs - // cmax = size of charnumarray conversion cache - // idpad = zeros to pad record IDs with - version = '2.6.2'; // proposed mmikowski 2012-08-06 - TC = 1; - idpad = '000000'; - cmax = 1000; - API = {}; - - protectJSON = function ( t ) { - // **************************************** - // * - // * Takes: a variable - // * Returns: the variable if object/array or the parsed variable if JSON - // * - // **************************************** - if ( TAFFY.isArray( t ) || TAFFY.isObject( t ) ){ - return t; - } - else { - return JSON.parse( t ); - } - }; - - each = function ( a, fun, u ) { - var r, i, x, y; - // **************************************** - // * - // * Takes: - // * a = an object/value or an array of objects/values - // * f = a function - // * u = optional flag to describe how to handle undefined values - // in array of values. True: pass them to the functions, - // False: skip. Default False; - // * Purpose: Used to loop over arrays - // * - // **************************************** - if ( a && ((T.isArray( a ) && a.length === 1) || (!T.isArray( a ))) ){ - fun( (T.isArray( a )) ? a[0] : a, 0 ); - } - else { - for ( r, i, x = 0, a = (T.isArray( a )) ? a : [a], y = a.length; - x < y; x++ ) - { - i = a[x]; - if ( !T.isUndefined( i ) || (u || false) ){ - r = fun( i, x ); - if ( r === T.EXIT ){ - break; - } - - } - } - } - }; - - eachin = function ( o, fun ) { - // **************************************** - // * - // * Takes: - // * o = an object - // * f = a function - // * Purpose: Used to loop over objects - // * - // **************************************** - var x = 0, r, i; - - for ( i in o ){ - if ( o.hasOwnProperty( i ) ){ - r = fun( o[i], i, x++ ); - if ( r === T.EXIT ){ - break; - } - } - } - - }; - - API.extend = function ( m, f ) { - // **************************************** - // * - // * Takes: method name, function - // * Purpose: Add a custom method to the API - // * - // **************************************** - API[m] = function () { - return f.apply( this, arguments ); - }; - }; - - isIndexable = function ( f ) { - var i; - // Check to see if record ID - if ( T.isString( f ) && /[t][0-9]*[r][0-9]*/i.test( f ) ){ - return true; - } - // Check to see if record - if ( T.isObject( f ) && f.___id && f.___s ){ - return true; - } - - // Check to see if array of indexes - if ( T.isArray( f ) ){ - i = true; - each( f, function ( r ) { - if ( !isIndexable( r ) ){ - i = false; - - return TAFFY.EXIT; - } - }); - return i; - } - - return false; - }; - - runFilters = function ( r, filter ) { - // **************************************** - // * - // * Takes: takes a record and a collection of filters - // * Returns: true if the record matches, false otherwise - // **************************************** - var match = true; - - - each( filter, function ( mf ) { - switch ( T.typeOf( mf ) ){ - case 'function': - // run function - if ( !mf.apply( r ) ){ - match = false; - return TAFFY.EXIT; - } - break; - case 'array': - // loop array and treat like a SQL or - match = (mf.length === 1) ? (runFilters( r, mf[0] )) : - (mf.length === 2) ? (runFilters( r, mf[0] ) || - runFilters( r, mf[1] )) : - (mf.length === 3) ? (runFilters( r, mf[0] ) || - runFilters( r, mf[1] ) || runFilters( r, mf[2] )) : - (mf.length === 4) ? (runFilters( r, mf[0] ) || - runFilters( r, mf[1] ) || runFilters( r, mf[2] ) || - runFilters( r, mf[3] )) : false; - if ( mf.length > 4 ){ - each( mf, function ( f ) { - if ( runFilters( r, f ) ){ - match = true; - } - }); - } - break; - } - }); - - return match; - }; - - returnFilter = function ( f ) { - // **************************************** - // * - // * Takes: filter object - // * Returns: a filter function - // * Purpose: Take a filter object and return a function that can be used to compare - // * a TaffyDB record to see if the record matches a query - // **************************************** - var nf = []; - if ( T.isString( f ) && /[t][0-9]*[r][0-9]*/i.test( f ) ){ - f = { ___id : f }; - } - if ( T.isArray( f ) ){ - // if we are working with an array - - each( f, function ( r ) { - // loop the array and return a filter func for each value - nf.push( returnFilter( r ) ); - }); - // now build a func to loop over the filters and return true if ANY of the filters match - // This handles logical OR expressions - f = function () { - var that = this, match = false; - each( nf, function ( f ) { - if ( runFilters( that, f ) ){ - match = true; - } - }); - return match; - }; - return f; - - } - // if we are dealing with an Object - if ( T.isObject( f ) ){ - if ( T.isObject( f ) && f.___id && f.___s ){ - f = { ___id : f.___id }; - } - - // Loop over each value on the object to prep match type and match value - eachin( f, function ( v, i ) { - - // default match type to IS/Equals - if ( !T.isObject( v ) ){ - v = { - 'is' : v - }; - } - // loop over each value on the value object - if any - eachin( v, function ( mtest, s ) { - // s = match type, e.g. is, hasAll, like, etc - var c = [], looper; - - // function to loop and apply filter - looper = (s === 'hasAll') ? - function ( mtest, func ) { - func( mtest ); - } : each; - - // loop over each test - looper( mtest, function ( mtest ) { - - // su = match success - // f = match false - var su = true, f = false, matchFunc; - - - // push a function onto the filter collection to do the matching - matchFunc = function () { - - // get the value from the record - var - mvalue = this[i], - eqeq = '==', - bangeq = '!=', - eqeqeq = '===', - lt = '<', - gt = '>', - lteq = '<=', - gteq = '>=', - bangeqeq = '!==', - r - ; - - - if ( (s.indexOf( '!' ) === 0) && s !== bangeq && - s !== bangeqeq ) - { - // if the filter name starts with ! as in '!is' then reverse the match logic and remove the ! - su = false; - s = s.substring( 1, s.length ); - } - // get the match results based on the s/match type - /*jslint eqeq : true */ - r = ( - (s === 'regex') ? (mtest.test( mvalue )) : (s === 'lt' || s === lt) - ? (mvalue < mtest) : (s === 'gt' || s === gt) - ? (mvalue > mtest) : (s === 'lte' || s === lteq) - ? (mvalue <= mtest) : (s === 'gte' || s === gteq) - ? (mvalue >= mtest) : (s === 'left') - ? (mvalue.indexOf( mtest ) === 0) : (s === 'leftnocase') - ? (mvalue.toLowerCase().indexOf( mtest.toLowerCase() ) - === 0) : (s === 'right') - ? (mvalue.substring( (mvalue.length - mtest.length) ) - === mtest) : (s === 'rightnocase') - ? (mvalue.toLowerCase().substring( - (mvalue.length - mtest.length) ) === mtest.toLowerCase()) - : (s === 'like') - ? (mvalue.indexOf( mtest ) >= 0) : (s === 'likenocase') - ? (mvalue.toLowerCase().indexOf(mtest.toLowerCase()) >= 0) - : (s === eqeqeq || s === 'is') - ? (mvalue === mtest) : (s === eqeq) - ? (mvalue == mtest) : (s === bangeqeq) - ? (mvalue !== mtest) : (s === bangeq) - ? (mvalue != mtest) : (s === 'isnocase') - ? (mvalue.toLowerCase - ? mvalue.toLowerCase() === mtest.toLowerCase() - : mvalue === mtest) : (s === 'has') - ? (T.has( mvalue, mtest )) : (s === 'hasall') - ? (T.hasAll( mvalue, mtest )) : ( - s.indexOf( 'is' ) === -1 - && !TAFFY.isNull( mvalue ) - && !TAFFY.isUndefined( mvalue ) - && !TAFFY.isObject( mtest ) - && !TAFFY.isArray( mtest ) - ) - ? (mtest === mvalue[s]) - : (T[s] && T.isFunction( T[s] ) - && s.indexOf( 'is' ) === 0) - ? T[s]( mvalue ) === mtest - : (T[s] && T.isFunction( T[s] )) - ? T[s]( mvalue, mtest ) : (false) - ); - /*jslint eqeq : false */ - r = (r && !su) ? false : (!r && !su) ? true : r; - - return r; - }; - c.push( matchFunc ); - - }); - // if only one filter in the collection push it onto the filter list without the array - if ( c.length === 1 ){ - - nf.push( c[0] ); - } - else { - // else build a function to loop over all the filters and return true only if ALL match - // this is a logical AND - nf.push( function () { - var that = this, match = false; - each( c, function ( f ) { - if ( f.apply( that ) ){ - match = true; - } - }); - return match; - }); - } - }); - }); - // finally return a single function that wraps all the other functions and will run a query - // where all functions have to return true for a record to appear in a query result - f = function () { - var that = this, match = true; - // faster if less than 4 functions - match = (nf.length === 1 && !nf[0].apply( that )) ? false : - (nf.length === 2 && - (!nf[0].apply( that ) || !nf[1].apply( that ))) ? false : - (nf.length === 3 && - (!nf[0].apply( that ) || !nf[1].apply( that ) || - !nf[2].apply( that ))) ? false : - (nf.length === 4 && - (!nf[0].apply( that ) || !nf[1].apply( that ) || - !nf[2].apply( that ) || !nf[3].apply( that ))) ? false - : true; - if ( nf.length > 4 ){ - each( nf, function ( f ) { - if ( !runFilters( that, f ) ){ - match = false; - } - }); - } - return match; - }; - return f; - } - - // if function - if ( T.isFunction( f ) ){ - return f; - } - }; - - orderByCol = function ( ar, o ) { - // **************************************** - // * - // * Takes: takes an array and a sort object - // * Returns: the array sorted - // * Purpose: Accept filters such as "[col], [col2]" or "[col] desc" and sort on those columns - // * - // **************************************** - - var sortFunc = function ( a, b ) { - // function to pass to the native array.sort to sort an array - var r = 0; - - T.each( o, function ( sd ) { - // loop over the sort instructions - // get the column name - var o, col, dir, c, d; - o = sd.split( ' ' ); - col = o[0]; - - // get the direction - dir = (o.length === 1) ? "logical" : o[1]; - - - if ( dir === 'logical' ){ - // if dir is logical than grab the charnum arrays for the two values we are looking at - c = numcharsplit( a[col] ); - d = numcharsplit( b[col] ); - // loop over the charnumarrays until one value is higher than the other - T.each( (c.length <= d.length) ? c : d, function ( x, i ) { - if ( c[i] < d[i] ){ - r = -1; - return TAFFY.EXIT; - } - else if ( c[i] > d[i] ){ - r = 1; - return TAFFY.EXIT; - } - } ); - } - else if ( dir === 'logicaldesc' ){ - // if logicaldesc than grab the charnum arrays for the two values we are looking at - c = numcharsplit( a[col] ); - d = numcharsplit( b[col] ); - // loop over the charnumarrays until one value is lower than the other - T.each( (c.length <= d.length) ? c : d, function ( x, i ) { - if ( c[i] > d[i] ){ - r = -1; - return TAFFY.EXIT; - } - else if ( c[i] < d[i] ){ - r = 1; - return TAFFY.EXIT; - } - } ); - } - else if ( dir === 'asec' && a[col] < b[col] ){ - // if asec - default - check to see which is higher - r = -1; - return T.EXIT; - } - else if ( dir === 'asec' && a[col] > b[col] ){ - // if asec - default - check to see which is higher - r = 1; - return T.EXIT; - } - else if ( dir === 'desc' && a[col] > b[col] ){ - // if desc check to see which is lower - r = -1; - return T.EXIT; - - } - else if ( dir === 'desc' && a[col] < b[col] ){ - // if desc check to see which is lower - r = 1; - return T.EXIT; - - } - // if r is still 0 and we are doing a logical sort than look to see if one array is longer than the other - if ( r === 0 && dir === 'logical' && c.length < d.length ){ - r = -1; - } - else if ( r === 0 && dir === 'logical' && c.length > d.length ){ - r = 1; - } - else if ( r === 0 && dir === 'logicaldesc' && c.length > d.length ){ - r = -1; - } - else if ( r === 0 && dir === 'logicaldesc' && c.length < d.length ){ - r = 1; - } - - if ( r !== 0 ){ - return T.EXIT; - } - - - } ); - return r; - }; - // call the sort function and return the newly sorted array - return (ar && ar.push) ? ar.sort( sortFunc ) : ar; - - - }; - - // **************************************** - // * - // * Takes: a string containing numbers and letters and turn it into an array - // * Returns: return an array of numbers and letters - // * Purpose: Used for logical sorting. String Example: 12ABC results: [12,'ABC'] - // **************************************** - (function () { - // creates a cache for numchar conversions - var cache = {}, cachcounter = 0; - // creates the numcharsplit function - numcharsplit = function ( thing ) { - // if over 1000 items exist in the cache, clear it and start over - if ( cachcounter > cmax ){ - cache = {}; - cachcounter = 0; - } - - // if a cache can be found for a numchar then return its array value - return cache['_' + thing] || (function () { - // otherwise do the conversion - // make sure it is a string and setup so other variables - var nthing = String( thing ), - na = [], - rv = '_', - rt = '', - x, xx, c; - - // loop over the string char by char - for ( x = 0, xx = nthing.length; x < xx; x++ ){ - // take the char at each location - c = nthing.charCodeAt( x ); - // check to see if it is a valid number char and append it to the array. - // if last char was a string push the string to the charnum array - if ( ( c >= 48 && c <= 57 ) || c === 46 ){ - if ( rt !== 'n' ){ - rt = 'n'; - na.push( rv.toLowerCase() ); - rv = ''; - } - rv = rv + nthing.charAt( x ); - } - else { - // check to see if it is a valid string char and append to string - // if last char was a number push the whole number to the charnum array - if ( rt !== 's' ){ - rt = 's'; - na.push( parseFloat( rv ) ); - rv = ''; - } - rv = rv + nthing.charAt( x ); - } - } - // once done, push the last value to the charnum array and remove the first uneeded item - na.push( (rt === 'n') ? parseFloat( rv ) : rv.toLowerCase() ); - na.shift(); - // add to cache - cache['_' + thing] = na; - cachcounter++; - // return charnum array - return na; - }()); - }; - }()); - - // **************************************** - // * - // * Runs a query - // **************************************** - - - run = function () { - this.context( { - results : this.getDBI().query( this.context() ) - }); - - }; - - API.extend( 'filter', function () { - // **************************************** - // * - // * Takes: takes unlimited filter objects as arguments - // * Returns: method collection - // * Purpose: Take filters as objects and cache functions for later lookup when a query is run - // **************************************** - var - nc = TAFFY.mergeObj( this.context(), { run : null } ), - nq = [] - ; - each( nc.q, function ( v ) { - nq.push( v ); - }); - nc.q = nq; - // Hadnle passing of ___ID or a record on lookup. - each( arguments, function ( f ) { - nc.q.push( returnFilter( f ) ); - nc.filterRaw.push( f ); - }); - - return this.getroot( nc ); - }); - - API.extend( 'order', function ( o ) { - // **************************************** - // * - // * Purpose: takes a string and creates an array of order instructions to be used with a query - // **************************************** - - o = o.split( ',' ); - var x = [], nc; - - each( o, function ( r ) { - x.push( r.replace( /^\s*/, '' ).replace( /\s*$/, '' ) ); - }); - - nc = TAFFY.mergeObj( this.context(), {sort : null} ); - nc.order = x; - - return this.getroot( nc ); - }); - - API.extend( 'limit', function ( n ) { - // **************************************** - // * - // * Purpose: takes a limit number to limit the number of rows returned by a query. Will update the results - // * of a query - // **************************************** - var nc = TAFFY.mergeObj( this.context(), {}), - limitedresults - ; - - nc.limit = n; - - if ( nc.run && nc.sort ){ - limitedresults = []; - each( nc.results, function ( i, x ) { - if ( (x + 1) > n ){ - return TAFFY.EXIT; - } - limitedresults.push( i ); - }); - nc.results = limitedresults; - } - - return this.getroot( nc ); - }); - - API.extend( 'start', function ( n ) { - // **************************************** - // * - // * Purpose: takes a limit number to limit the number of rows returned by a query. Will update the results - // * of a query - // **************************************** - var nc = TAFFY.mergeObj( this.context(), {} ), - limitedresults - ; - - nc.start = n; - - if ( nc.run && nc.sort && !nc.limit ){ - limitedresults = []; - each( nc.results, function ( i, x ) { - if ( (x + 1) > n ){ - limitedresults.push( i ); - } - }); - nc.results = limitedresults; - } - else { - nc = TAFFY.mergeObj( this.context(), {run : null, start : n} ); - } - - return this.getroot( nc ); - }); - - API.extend( 'update', function ( arg0, arg1, arg2 ) { - // **************************************** - // * - // * Takes: a object and passes it off DBI update method for all matched records - // **************************************** - var runEvent = true, o = {}, args = arguments, that; - if ( TAFFY.isString( arg0 ) && - (arguments.length === 2 || arguments.length === 3) ) - { - o[arg0] = arg1; - if ( arguments.length === 3 ){ - runEvent = arg2; - } - } - else { - o = arg0; - if ( args.length === 2 ){ - runEvent = arg1; - } - } - - that = this; - run.call( this ); - each( this.context().results, function ( r ) { - var c = o; - if ( TAFFY.isFunction( c ) ){ - c = c.apply( TAFFY.mergeObj( r, {} ) ); - } - else { - if ( T.isFunction( c ) ){ - c = c( TAFFY.mergeObj( r, {} ) ); - } - } - if ( TAFFY.isObject( c ) ){ - that.getDBI().update( r.___id, c, runEvent ); - } - }); - if ( this.context().results.length ){ - this.context( { run : null }); - } - return this; - }); - API.extend( 'remove', function ( runEvent ) { - // **************************************** - // * - // * Purpose: removes records from the DB via the remove and removeCommit DBI methods - // **************************************** - var that = this, c = 0; - run.call( this ); - each( this.context().results, function ( r ) { - that.getDBI().remove( r.___id ); - c++; - }); - if ( this.context().results.length ){ - this.context( { - run : null - }); - that.getDBI().removeCommit( runEvent ); - } - - return c; - }); - - - API.extend( 'count', function () { - // **************************************** - // * - // * Returns: The length of a query result - // **************************************** - run.call( this ); - return this.context().results.length; - }); - - API.extend( 'callback', function ( f, delay ) { - // **************************************** - // * - // * Returns null; - // * Runs a function on return of run.call - // **************************************** - if ( f ){ - var that = this; - setTimeout( function () { - run.call( that ); - f.call( that.getroot( that.context() ) ); - }, delay || 0 ); - } - - - return null; - }); - - API.extend( 'get', function () { - // **************************************** - // * - // * Returns: An array of all matching records - // **************************************** - run.call( this ); - return this.context().results; - }); - - API.extend( 'stringify', function () { - // **************************************** - // * - // * Returns: An JSON string of all matching records - // **************************************** - return JSON.stringify( this.get() ); - }); - API.extend( 'first', function () { - // **************************************** - // * - // * Returns: The first matching record - // **************************************** - run.call( this ); - return this.context().results[0] || false; - }); - API.extend( 'last', function () { - // **************************************** - // * - // * Returns: The last matching record - // **************************************** - run.call( this ); - return this.context().results[this.context().results.length - 1] || - false; - }); - - - API.extend( 'sum', function () { - // **************************************** - // * - // * Takes: column to sum up - // * Returns: Sums the values of a column - // **************************************** - var total = 0, that = this; - run.call( that ); - each( arguments, function ( c ) { - each( that.context().results, function ( r ) { - total = total + r[c]; - }); - }); - return total; - }); - - API.extend( 'min', function ( c ) { - // **************************************** - // * - // * Takes: column to find min - // * Returns: the lowest value - // **************************************** - var lowest = null; - run.call( this ); - each( this.context().results, function ( r ) { - if ( lowest === null || r[c] < lowest ){ - lowest = r[c]; - } - }); - return lowest; - }); - - // Taffy innerJoin Extension (OCD edition) - // ======================================= - // - // How to Use - // ********** - // - // left_table.innerJoin( right_table, condition1 <,... conditionN> ) - // - // A condition can take one of 2 forms: - // - // 1. An ARRAY with 2 or 3 values: - // A column name from the left table, an optional comparison string, - // and column name from the right table. The condition passes if the test - // indicated is true. If the condition string is omitted, '===' is assumed. - // EXAMPLES: [ 'last_used_time', '>=', 'current_use_time' ], [ 'user_id','id' ] - // - // 2. A FUNCTION: - // The function receives a left table row and right table row during the - // cartesian join. If the function returns true for the rows considered, - // the merged row is included in the result set. - // EXAMPLE: function (l,r){ return l.name === r.label; } - // - // Conditions are considered in the order they are presented. Therefore the best - // performance is realized when the least expensive and highest prune-rate - // conditions are placed first, since if they return false Taffy skips any - // further condition tests. - // - // Other notes - // *********** - // - // This code passes jslint with the exception of 2 warnings about - // the '==' and '!=' lines. We can't do anything about that short of - // deleting the lines. - // - // Credits - // ******* - // - // Heavily based upon the work of Ian Toltz. - // Revisions to API by Michael Mikowski. - // Code convention per standards in http://manning.com/mikowski - (function () { - var innerJoinFunction = (function () { - var fnCompareList, fnCombineRow, fnMain; - - fnCompareList = function ( left_row, right_row, arg_list ) { - var data_lt, data_rt, op_code, error; - - if ( arg_list.length === 2 ){ - data_lt = left_row[arg_list[0]]; - op_code = '==='; - data_rt = right_row[arg_list[1]]; - } - else { - data_lt = left_row[arg_list[0]]; - op_code = arg_list[1]; - data_rt = right_row[arg_list[2]]; - } - - /*jslint eqeq : true */ - switch ( op_code ){ - case '===' : - return data_lt === data_rt; - case '!==' : - return data_lt !== data_rt; - case '<' : - return data_lt < data_rt; - case '>' : - return data_lt > data_rt; - case '<=' : - return data_lt <= data_rt; - case '>=' : - return data_lt >= data_rt; - case '==' : - return data_lt == data_rt; - case '!=' : - return data_lt != data_rt; - default : - throw String( op_code ) + ' is not supported'; - } - // 'jslint eqeq : false' here results in - // "Unreachable '/*jslint' after 'return'". - // We don't need it though, as the rule exception - // is discarded at the end of this functional scope - }; - - fnCombineRow = function ( left_row, right_row ) { - var out_map = {}, i, prefix; - - for ( i in left_row ){ - if ( left_row.hasOwnProperty( i ) ){ - out_map[i] = left_row[i]; - } - } - for ( i in right_row ){ - if ( right_row.hasOwnProperty( i ) && i !== '___id' && - i !== '___s' ) - { - prefix = !TAFFY.isUndefined( out_map[i] ) ? 'right_' : ''; - out_map[prefix + String( i ) ] = right_row[i]; - } - } - return out_map; - }; - - fnMain = function ( table ) { - var - right_table, i, - arg_list = arguments, - arg_length = arg_list.length, - result_list = [] - ; - - if ( typeof table.filter !== 'function' ){ - if ( table.TAFFY ){ right_table = table(); } - else { - throw 'TAFFY DB or result not supplied'; - } - } - else { right_table = table; } - - this.context( { - results : this.getDBI().query( this.context() ) - } ); - - TAFFY.each( this.context().results, function ( left_row ) { - right_table.each( function ( right_row ) { - var arg_data, is_ok = true; - CONDITION: - for ( i = 1; i < arg_length; i++ ){ - arg_data = arg_list[i]; - if ( typeof arg_data === 'function' ){ - is_ok = arg_data( left_row, right_row ); - } - else if ( typeof arg_data === 'object' && arg_data.length ){ - is_ok = fnCompareList( left_row, right_row, arg_data ); - } - else { - is_ok = false; - } - - if ( !is_ok ){ break CONDITION; } // short circuit - } - - if ( is_ok ){ - result_list.push( fnCombineRow( left_row, right_row ) ); - } - } ); - } ); - return TAFFY( result_list )(); - }; - - return fnMain; - }()); - - API.extend( 'join', innerJoinFunction ); - }()); - - API.extend( 'max', function ( c ) { - // **************************************** - // * - // * Takes: column to find max - // * Returns: the highest value - // **************************************** - var highest = null; - run.call( this ); - each( this.context().results, function ( r ) { - if ( highest === null || r[c] > highest ){ - highest = r[c]; - } - }); - return highest; - }); - - API.extend( 'select', function () { - // **************************************** - // * - // * Takes: columns to select values into an array - // * Returns: array of values - // * Note if more than one column is given an array of arrays is returned - // **************************************** - - var ra = [], args = arguments; - run.call( this ); - if ( arguments.length === 1 ){ - - each( this.context().results, function ( r ) { - - ra.push( r[args[0]] ); - }); - } - else { - each( this.context().results, function ( r ) { - var row = []; - each( args, function ( c ) { - row.push( r[c] ); - }); - ra.push( row ); - }); - } - return ra; - }); - API.extend( 'distinct', function () { - // **************************************** - // * - // * Takes: columns to select unique alues into an array - // * Returns: array of values - // * Note if more than one column is given an array of arrays is returned - // **************************************** - var ra = [], args = arguments; - run.call( this ); - if ( arguments.length === 1 ){ - - each( this.context().results, function ( r ) { - var v = r[args[0]], dup = false; - each( ra, function ( d ) { - if ( v === d ){ - dup = true; - return TAFFY.EXIT; - } - }); - if ( !dup ){ - ra.push( v ); - } - }); - } - else { - each( this.context().results, function ( r ) { - var row = [], dup = false; - each( args, function ( c ) { - row.push( r[c] ); - }); - each( ra, function ( d ) { - var ldup = true; - each( args, function ( c, i ) { - if ( row[i] !== d[i] ){ - ldup = false; - return TAFFY.EXIT; - } - }); - if ( ldup ){ - dup = true; - return TAFFY.EXIT; - } - }); - if ( !dup ){ - ra.push( row ); - } - }); - } - return ra; - }); - API.extend( 'supplant', function ( template, returnarray ) { - // **************************************** - // * - // * Takes: a string template formated with key to be replaced with values from the rows, flag to determine if we want array of strings - // * Returns: array of values or a string - // **************************************** - var ra = []; - run.call( this ); - each( this.context().results, function ( r ) { - // TODO: The curly braces used to be unescaped - ra.push( template.replace( /\{([^\{\}]*)\}/g, function ( a, b ) { - var v = r[b]; - return typeof v === 'string' || typeof v === 'number' ? v : a; - } ) ); - }); - return (!returnarray) ? ra.join( "" ) : ra; - }); - - - API.extend( 'each', function ( m ) { - // **************************************** - // * - // * Takes: a function - // * Purpose: loops over every matching record and applies the function - // **************************************** - run.call( this ); - each( this.context().results, m ); - return this; - }); - API.extend( 'map', function ( m ) { - // **************************************** - // * - // * Takes: a function - // * Purpose: loops over every matching record and applies the function, returing the results in an array - // **************************************** - var ra = []; - run.call( this ); - each( this.context().results, function ( r ) { - ra.push( m( r ) ); - }); - return ra; - }); - - - - T = function ( d ) { - // **************************************** - // * - // * T is the main TAFFY object - // * Takes: an array of objects or JSON - // * Returns a new TAFFYDB - // **************************************** - var TOb = [], - ID = {}, - RC = 1, - settings = { - template : false, - onInsert : false, - onUpdate : false, - onRemove : false, - onDBChange : false, - storageName : false, - forcePropertyCase : null, - cacheSize : 100, - name : '' - }, - dm = new Date(), - CacheCount = 0, - CacheClear = 0, - Cache = {}, - DBI, runIndexes, root - ; - // **************************************** - // * - // * TOb = this database - // * ID = collection of the record IDs and locations within the DB, used for fast lookups - // * RC = record counter, used for creating IDs - // * settings.template = the template to merge all new records with - // * settings.onInsert = event given a copy of the newly inserted record - // * settings.onUpdate = event given the original record, the changes, and the new record - // * settings.onRemove = event given the removed record - // * settings.forcePropertyCase = on insert force the proprty case to be lower or upper. default lower, null/undefined will leave case as is - // * dm = the modify date of the database, used for query caching - // **************************************** - - - runIndexes = function ( indexes ) { - // **************************************** - // * - // * Takes: a collection of indexes - // * Returns: collection with records matching indexed filters - // **************************************** - - var records = [], UniqueEnforce = false; - - if ( indexes.length === 0 ){ - return TOb; - } - - each( indexes, function ( f ) { - // Check to see if record ID - if ( T.isString( f ) && /[t][0-9]*[r][0-9]*/i.test( f ) && - TOb[ID[f]] ) - { - records.push( TOb[ID[f]] ); - UniqueEnforce = true; - } - // Check to see if record - if ( T.isObject( f ) && f.___id && f.___s && - TOb[ID[f.___id]] ) - { - records.push( TOb[ID[f.___id]] ); - UniqueEnforce = true; - } - // Check to see if array of indexes - if ( T.isArray( f ) ){ - each( f, function ( r ) { - each( runIndexes( r ), function ( rr ) { - records.push( rr ); - }); - - }); - } - }); - if ( UniqueEnforce && records.length > 1 ){ - records = []; - } - - return records; - }; - - DBI = { - // **************************************** - // * - // * The DBI is the internal DataBase Interface that interacts with the data - // **************************************** - dm : function ( nd ) { - // **************************************** - // * - // * Takes: an optional new modify date - // * Purpose: used to get and set the DB modify date - // **************************************** - if ( nd ){ - dm = nd; - Cache = {}; - CacheCount = 0; - CacheClear = 0; - } - if ( settings.onDBChange ){ - setTimeout( function () { - settings.onDBChange.call( TOb ); - }, 0 ); - } - if ( settings.storageName ){ - setTimeout( function () { - localStorage.setItem( 'taffy_' + settings.storageName, - JSON.stringify( TOb ) ); - }); - } - return dm; - }, - insert : function ( i, runEvent ) { - // **************************************** - // * - // * Takes: a new record to insert - // * Purpose: merge the object with the template, add an ID, insert into DB, call insert event - // **************************************** - var columns = [], - records = [], - input = protectJSON( i ) - ; - each( input, function ( v, i ) { - var nv, o; - if ( T.isArray( v ) && i === 0 ){ - each( v, function ( av ) { - - columns.push( (settings.forcePropertyCase === 'lower') - ? av.toLowerCase() - : (settings.forcePropertyCase === 'upper') - ? av.toUpperCase() : av ); - }); - return true; - } - else if ( T.isArray( v ) ){ - nv = {}; - each( v, function ( av, ai ) { - nv[columns[ai]] = av; - }); - v = nv; - - } - else if ( T.isObject( v ) && settings.forcePropertyCase ){ - o = {}; - - eachin( v, function ( av, ai ) { - o[(settings.forcePropertyCase === 'lower') ? ai.toLowerCase() - : (settings.forcePropertyCase === 'upper') - ? ai.toUpperCase() : ai] = v[ai]; - }); - v = o; - } - - RC++; - v.___id = 'T' + String( idpad + TC ).slice( -6 ) + 'R' + - String( idpad + RC ).slice( -6 ); - v.___s = true; - records.push( v.___id ); - if ( settings.template ){ - v = T.mergeObj( settings.template, v ); - } - TOb.push( v ); - - ID[v.___id] = TOb.length - 1; - if ( settings.onInsert && - (runEvent || TAFFY.isUndefined( runEvent )) ) - { - settings.onInsert.call( v ); - } - DBI.dm( new Date() ); - }); - return root( records ); - }, - sort : function ( o ) { - // **************************************** - // * - // * Purpose: Change the sort order of the DB itself and reset the ID bucket - // **************************************** - TOb = orderByCol( TOb, o.split( ',' ) ); - ID = {}; - each( TOb, function ( r, i ) { - ID[r.___id] = i; - }); - DBI.dm( new Date() ); - return true; - }, - update : function ( id, changes, runEvent ) { - // **************************************** - // * - // * Takes: the ID of record being changed and the changes - // * Purpose: Update a record and change some or all values, call the on update method - // **************************************** - - var nc = {}, or, nr, tc, hasChange; - if ( settings.forcePropertyCase ){ - eachin( changes, function ( v, p ) { - nc[(settings.forcePropertyCase === 'lower') ? p.toLowerCase() - : (settings.forcePropertyCase === 'upper') ? p.toUpperCase() - : p] = v; - }); - changes = nc; - } - - or = TOb[ID[id]]; - nr = T.mergeObj( or, changes ); - - tc = {}; - hasChange = false; - eachin( nr, function ( v, i ) { - if ( TAFFY.isUndefined( or[i] ) || or[i] !== v ){ - tc[i] = v; - hasChange = true; - } - }); - if ( hasChange ){ - if ( settings.onUpdate && - (runEvent || TAFFY.isUndefined( runEvent )) ) - { - settings.onUpdate.call( nr, TOb[ID[id]], tc ); - } - TOb[ID[id]] = nr; - DBI.dm( new Date() ); - } - }, - remove : function ( id ) { - // **************************************** - // * - // * Takes: the ID of record to be removed - // * Purpose: remove a record, changes its ___s value to false - // **************************************** - TOb[ID[id]].___s = false; - }, - removeCommit : function ( runEvent ) { - var x; - // **************************************** - // * - // * - // * Purpose: loop over all records and remove records with ___s = false, call onRemove event, clear ID - // **************************************** - for ( x = TOb.length - 1; x > -1; x-- ){ - - if ( !TOb[x].___s ){ - if ( settings.onRemove && - (runEvent || TAFFY.isUndefined( runEvent )) ) - { - settings.onRemove.call( TOb[x] ); - } - ID[TOb[x].___id] = undefined; - TOb.splice( x, 1 ); - } - } - ID = {}; - each( TOb, function ( r, i ) { - ID[r.___id] = i; - }); - DBI.dm( new Date() ); - }, - query : function ( context ) { - // **************************************** - // * - // * Takes: the context object for a query and either returns a cache result or a new query result - // **************************************** - var returnq, cid, results, indexed, limitq, ni; - - if ( settings.cacheSize ) { - cid = ''; - each( context.filterRaw, function ( r ) { - if ( T.isFunction( r ) ){ - cid = 'nocache'; - return TAFFY.EXIT; - } - }); - if ( cid === '' ){ - cid = JSON.stringify( T.mergeObj( context, - {q : false, run : false, sort : false} ) ); - } - } - // Run a new query if there are no results or the run date has been cleared - if ( !context.results || !context.run || - (context.run && DBI.dm() > context.run) ) - { - results = []; - - // check Cache - - if ( settings.cacheSize && Cache[cid] ){ - - Cache[cid].i = CacheCount++; - return Cache[cid].results; - } - else { - // if no filter, return DB - if ( context.q.length === 0 && context.index.length === 0 ){ - each( TOb, function ( r ) { - results.push( r ); - }); - returnq = results; - } - else { - // use indexes - - indexed = runIndexes( context.index ); - - // run filters - each( indexed, function ( r ) { - // Run filter to see if record matches query - if ( context.q.length === 0 || runFilters( r, context.q ) ){ - results.push( r ); - } - }); - - returnq = results; - } - } - - - } - else { - // If query exists and run has not been cleared return the cache results - returnq = context.results; - } - // If a custom order array exists and the run has been clear or the sort has been cleared - if ( context.order.length > 0 && (!context.run || !context.sort) ){ - // order the results - returnq = orderByCol( returnq, context.order ); - } - - // If a limit on the number of results exists and it is less than the returned results, limit results - if ( returnq.length && - ((context.limit && context.limit < returnq.length) || - context.start) - ) { - limitq = []; - each( returnq, function ( r, i ) { - if ( !context.start || - (context.start && (i + 1) >= context.start) ) - { - if ( context.limit ){ - ni = (context.start) ? (i + 1) - context.start : i; - if ( ni < context.limit ){ - limitq.push( r ); - } - else if ( ni > context.limit ){ - return TAFFY.EXIT; - } - } - else { - limitq.push( r ); - } - } - }); - returnq = limitq; - } - - // update cache - if ( settings.cacheSize && cid !== 'nocache' ){ - CacheClear++; - - setTimeout( function () { - var bCounter, nc; - if ( CacheClear >= settings.cacheSize * 2 ){ - CacheClear = 0; - bCounter = CacheCount - settings.cacheSize; - nc = {}; - eachin( function ( r, k ) { - if ( r.i >= bCounter ){ - nc[k] = r; - } - }); - Cache = nc; - } - }, 0 ); - - Cache[cid] = { i : CacheCount++, results : returnq }; - } - return returnq; - } - }; - - - root = function () { - var iAPI, context; - // **************************************** - // * - // * The root function that gets returned when a new DB is created - // * Takes: unlimited filter arguments and creates filters to be run when a query is called - // **************************************** - // **************************************** - // * - // * iAPI is the the method collection valiable when a query has been started by calling dbname - // * Certain methods are or are not avaliable once you have started a query such as insert -- you can only insert into root - // **************************************** - iAPI = TAFFY.mergeObj( TAFFY.mergeObj( API, { insert : undefined } ), - { getDBI : function () { return DBI; }, - getroot : function ( c ) { return root.call( c ); }, - context : function ( n ) { - // **************************************** - // * - // * The context contains all the information to manage a query including filters, limits, and sorts - // **************************************** - if ( n ){ - context = TAFFY.mergeObj( context, - n.hasOwnProperty('results') - ? TAFFY.mergeObj( n, { run : new Date(), sort: new Date() }) - : n - ); - } - return context; - }, - extend : undefined - }); - - context = (this && this.q) ? this : { - limit : false, - start : false, - q : [], - filterRaw : [], - index : [], - order : [], - results : false, - run : null, - sort : null, - settings : settings - }; - // **************************************** - // * - // * Call the query method to setup a new query - // **************************************** - each( arguments, function ( f ) { - - if ( isIndexable( f ) ){ - context.index.push( f ); - } - else { - context.q.push( returnFilter( f ) ); - } - context.filterRaw.push( f ); - }); - - - return iAPI; - }; - - // **************************************** - // * - // * If new records have been passed on creation of the DB either as JSON or as an array/object, insert them - // **************************************** - TC++; - if ( d ){ - DBI.insert( d ); - } - - - root.insert = DBI.insert; - - root.merge = function ( i, key, runEvent ) { - var - search = {}, - finalSearch = [], - obj = {} - ; - - runEvent = runEvent || false; - key = key || 'id'; - - each( i, function ( o ) { - var existingObject; - search[key] = o[key]; - finalSearch.push( o[key] ); - existingObject = root( search ).first(); - if ( existingObject ){ - DBI.update( existingObject.___id, o, runEvent ); - } - else { - DBI.insert( o, runEvent ); - } - }); - - obj[key] = finalSearch; - return root( obj ); - }; - - root.TAFFY = true; - root.sort = DBI.sort; - // **************************************** - // * - // * These are the methods that can be accessed on off the root DB function. Example dbname.insert; - // **************************************** - root.settings = function ( n ) { - // **************************************** - // * - // * Getting and setting for this DB's settings/events - // **************************************** - if ( n ){ - settings = TAFFY.mergeObj( settings, n ); - if ( n.template ){ - - root().update( n.template ); - } - } - return settings; - }; - - // **************************************** - // * - // * These are the methods that can be accessed on off the root DB function. Example dbname.insert; - // **************************************** - root.store = function ( n ) { - // **************************************** - // * - // * Setup localstorage for this DB on a given name - // * Pull data into the DB as needed - // **************************************** - var r = false, i; - if ( localStorage ){ - if ( n ){ - i = localStorage.getItem( 'taffy_' + n ); - if ( i && i.length > 0 ){ - root.insert( i ); - r = true; - } - if ( TOb.length > 0 ){ - setTimeout( function () { - localStorage.setItem( 'taffy_' + settings.storageName, - JSON.stringify( TOb ) ); - }); - } - } - root.settings( {storageName : n} ); - } - return root; - }; - - // **************************************** - // * - // * Return root on DB creation and start having fun - // **************************************** - return root; - }; - // **************************************** - // * - // * Sets the global TAFFY object - // **************************************** - TAFFY = T; - - - // **************************************** - // * - // * Create public each method - // * - // **************************************** - T.each = each; - - // **************************************** - // * - // * Create public eachin method - // * - // **************************************** - T.eachin = eachin; - // **************************************** - // * - // * Create public extend method - // * Add a custom method to the API - // * - // **************************************** - T.extend = API.extend; - - - // **************************************** - // * - // * Creates TAFFY.EXIT value that can be returned to stop an each loop - // * - // **************************************** - TAFFY.EXIT = 'TAFFYEXIT'; - - // **************************************** - // * - // * Create public utility mergeObj method - // * Return a new object where items from obj2 - // * have replaced or been added to the items in - // * obj1 - // * Purpose: Used to combine objs - // * - // **************************************** - TAFFY.mergeObj = function ( ob1, ob2 ) { - var c = {}; - eachin( ob1, function ( v, n ) { c[n] = ob1[n]; }); - eachin( ob2, function ( v, n ) { c[n] = ob2[n]; }); - return c; - }; - - - // **************************************** - // * - // * Create public utility has method - // * Returns true if a complex object, array - // * or taffy collection contains the material - // * provided in the second argument - // * Purpose: Used to comare objects - // * - // **************************************** - TAFFY.has = function ( var1, var2 ) { - - var re = true, n; - - if ( (var1.TAFFY) ){ - re = var1( var2 ); - if ( re.length > 0 ){ - return true; - } - else { - return false; - } - } - else { - - switch ( T.typeOf( var1 ) ){ - case 'object': - if ( T.isObject( var2 ) ){ - eachin( var2, function ( v, n ) { - if ( re === true && !T.isUndefined( var1[n] ) && - var1.hasOwnProperty( n ) ) - { - re = T.has( var1[n], var2[n] ); - } - else { - re = false; - return TAFFY.EXIT; - } - }); - } - else if ( T.isArray( var2 ) ){ - each( var2, function ( v, n ) { - re = T.has( var1, var2[n] ); - if ( re ){ - return TAFFY.EXIT; - } - }); - } - else if ( T.isString( var2 ) ){ - if ( !TAFFY.isUndefined( var1[var2] ) ){ - return true; - } - else { - return false; - } - } - return re; - case 'array': - if ( T.isObject( var2 ) ){ - each( var1, function ( v, i ) { - re = T.has( var1[i], var2 ); - if ( re === true ){ - return TAFFY.EXIT; - } - }); - } - else if ( T.isArray( var2 ) ){ - each( var2, function ( v2, i2 ) { - each( var1, function ( v1, i1 ) { - re = T.has( var1[i1], var2[i2] ); - if ( re === true ){ - return TAFFY.EXIT; - } - }); - if ( re === true ){ - return TAFFY.EXIT; - } - }); - } - else if ( T.isString( var2 ) || T.isNumber( var2 ) ){ - for ( n = 0; n < var1.length; n++ ){ - re = T.has( var1[n], var2 ); - if ( re ){ - return true; - } - } - } - return re; - case 'string': - if ( T.isString( var2 ) && var2 === var1 ){ - return true; - } - break; - default: - if ( T.typeOf( var1 ) === T.typeOf( var2 ) && var1 === var2 ){ - return true; - } - break; - } - } - return false; - }; - - // **************************************** - // * - // * Create public utility hasAll method - // * Returns true if a complex object, array - // * or taffy collection contains the material - // * provided in the call - for arrays it must - // * contain all the material in each array item - // * Purpose: Used to comare objects - // * - // **************************************** - TAFFY.hasAll = function ( var1, var2 ) { - - var T = TAFFY, ar; - if ( T.isArray( var2 ) ){ - ar = true; - each( var2, function ( v ) { - ar = T.has( var1, v ); - if ( ar === false ){ - return TAFFY.EXIT; - } - }); - return ar; - } - else { - return T.has( var1, var2 ); - } - }; - - - // **************************************** - // * - // * typeOf Fixed in JavaScript as public utility - // * - // **************************************** - TAFFY.typeOf = function ( v ) { - var s = typeof v; - if ( s === 'object' ){ - if ( v ){ - if ( typeof v.length === 'number' && - !(v.propertyIsEnumerable( 'length' )) ) - { - s = 'array'; - } - } - else { - s = 'null'; - } - } - return s; - }; - - // **************************************** - // * - // * Create public utility getObjectKeys method - // * Returns an array of an objects keys - // * Purpose: Used to get the keys for an object - // * - // **************************************** - TAFFY.getObjectKeys = function ( ob ) { - var kA = []; - eachin( ob, function ( n, h ) { - kA.push( h ); - }); - kA.sort(); - return kA; - }; - - // **************************************** - // * - // * Create public utility isSameArray - // * Returns an array of an objects keys - // * Purpose: Used to get the keys for an object - // * - // **************************************** - TAFFY.isSameArray = function ( ar1, ar2 ) { - return (TAFFY.isArray( ar1 ) && TAFFY.isArray( ar2 ) && - ar1.join( ',' ) === ar2.join( ',' )) ? true : false; - }; - - // **************************************** - // * - // * Create public utility isSameObject method - // * Returns true if objects contain the same - // * material or false if they do not - // * Purpose: Used to comare objects - // * - // **************************************** - TAFFY.isSameObject = function ( ob1, ob2 ) { - var T = TAFFY, rv = true; - - if ( T.isObject( ob1 ) && T.isObject( ob2 ) ){ - if ( T.isSameArray( T.getObjectKeys( ob1 ), - T.getObjectKeys( ob2 ) ) ) - { - eachin( ob1, function ( v, n ) { - if ( ! ( (T.isObject( ob1[n] ) && T.isObject( ob2[n] ) && - T.isSameObject( ob1[n], ob2[n] )) || - (T.isArray( ob1[n] ) && T.isArray( ob2[n] ) && - T.isSameArray( ob1[n], ob2[n] )) || (ob1[n] === ob2[n]) ) - ) { - rv = false; - return TAFFY.EXIT; - } - }); - } - else { - rv = false; - } - } - else { - rv = false; - } - return rv; - }; - - // **************************************** - // * - // * Create public utility is[DataType] methods - // * Return true if obj is datatype, false otherwise - // * Purpose: Used to determine if arguments are of certain data type - // * - // * mmikowski 2012-08-06 refactored to make much less "magical": - // * fewer closures and passes jslint - // * - // **************************************** - - typeList = [ - 'String', 'Number', 'Object', 'Array', - 'Boolean', 'Null', 'Function', 'Undefined' - ]; - - makeTest = function ( thisKey ) { - return function ( data ) { - return TAFFY.typeOf( data ) === thisKey.toLowerCase() ? true : false; - }; - }; - - for ( idx = 0; idx < typeList.length; idx++ ){ - typeKey = typeList[idx]; - TAFFY['is' + typeKey] = makeTest( typeKey ); - } - } -}()); - -if ( typeof(exports) === 'object' ){ - exports.taffy = TAFFY; -} - diff --git a/rsc/scripts/jsdoc/node_modules/underscore/LICENSE b/rsc/scripts/jsdoc/node_modules/underscore/LICENSE deleted file mode 100644 index 61d28c08..00000000 --- a/rsc/scripts/jsdoc/node_modules/underscore/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud - -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/rsc/scripts/jsdoc/node_modules/underscore/package.json b/rsc/scripts/jsdoc/node_modules/underscore/package.json deleted file mode 100644 index 4507c010..00000000 --- a/rsc/scripts/jsdoc/node_modules/underscore/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "underscore", - "description": "JavaScript's functional programming helper library.", - "homepage": "http://underscorejs.org", - "keywords": [ - "util", - "functional", - "server", - "client", - "browser" - ], - "author": { - "name": "Jeremy Ashkenas", - "email": "jeremy@documentcloud.org" - }, - "repository": { - "type": "git", - "url": "git://github.com/documentcloud/underscore.git" - }, - "main": "underscore.js", - "version": "1.4.2", - "readme": " __\n /\\ \\ __\n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____\n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\\n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/\n \\ \\____/\n \\/___/\n\nUnderscore.js is a utility-belt library for JavaScript that provides\nsupport for the usual functional suspects (each, map, reduce, filter...)\nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://underscorejs.org\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n", - "_id": "underscore@1.4.2", - "_from": "underscore" -} diff --git a/rsc/scripts/jsdoc/node_modules/underscore/underscore.js b/rsc/scripts/jsdoc/node_modules/underscore/underscore.js deleted file mode 100644 index 1ebe2671..00000000 --- a/rsc/scripts/jsdoc/node_modules/underscore/underscore.js +++ /dev/null @@ -1,1200 +0,0 @@ -// Underscore.js 1.4.2 -// http://underscorejs.org -// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `global` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var push = ArrayProto.push, - slice = ArrayProto.slice, - concat = ArrayProto.concat, - unshift = ArrayProto.unshift, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root['_'] = _; - } - - // Current version. - _.VERSION = '1.4.2'; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects with the built-in `forEach`, arrays, and raw objects. - // Delegates to **ECMAScript 5**'s native `forEach` if available. - var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return; - if (nativeForEach && obj.forEach === nativeForEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - for (var key in obj) { - if (_.has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === breaker) return; - } - } - } - }; - - // Return the results of applying the iterator to each element. - // Delegates to **ECMAScript 5**'s native `map` if available. - _.map = _.collect = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); - each(obj, function(value, index, list) { - results[results.length] = iterator.call(context, value, index, list); - }); - return results; - }; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. - _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduce && obj.reduce === nativeReduce) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError('Reduce of empty array with no initial value'); - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - // Delegates to **ECMAScript 5**'s native `reduceRight` if available. - _.reduceRight = _.foldr = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { - if (context) iterator = _.bind(iterator, context); - return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); - } - var length = obj.length; - if (length !== +length) { - var keys = _.keys(obj); - length = keys.length; - } - each(obj, function(value, index, list) { - index = keys ? keys[--length] : --length; - if (!initial) { - memo = obj[index]; - initial = true; - } else { - memo = iterator.call(context, memo, obj[index], index, list); - } - }); - if (!initial) throw new TypeError('Reduce of empty array with no initial value'); - return memo; - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { - var result; - any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // Aliased as `select`. - _.filter = _.select = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); - each(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - each(obj, function(value, index, list) { - if (!iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = true; - if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); - each(obj, function(value, index, list) { - if (!(result = result && iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = false; - if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); - each(obj, function(value, index, list) { - if (result || (result = iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - var found = false; - if (obj == null) return found; - if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; - found = any(obj, function(value) { - return value === target; - }); - return found; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - return _.map(obj, function(value) { - return (_.isFunction(method) ? method : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // with specific `key:value` pairs. - _.where = function(obj, attrs) { - if (_.isEmpty(attrs)) return []; - return _.filter(obj, function(value) { - for (var key in attrs) { - if (attrs[key] !== value[key]) return false; - } - return true; - }); - }; - - // Return the maximum element or (element-based computation). - // Can't optimize arrays of integers longer than 65,535 elements. - // See: https://bugs.webkit.org/show_bug.cgi?id=80797 - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.max.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed >= result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.min.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Shuffle an array. - _.shuffle = function(obj) { - var rand; - var index = 0; - var shuffled = []; - each(obj, function(value) { - rand = _.random(index++); - shuffled[index - 1] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; - - // An internal function to generate lookup iterators. - var lookupIterator = function(value) { - return _.isFunction(value) ? value : function(obj){ return obj[value]; }; - }; - - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, value, context) { - var iterator = lookupIterator(value); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value : value, - index : index, - criteria : iterator.call(context, value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index < right.index ? -1 : 1; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(obj, value, context, behavior) { - var result = {}; - var iterator = lookupIterator(value); - each(obj, function(value, index) { - var key = iterator.call(context, value, index, obj); - behavior(result, key, value); - }); - return result; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = function(obj, value, context) { - return group(obj, value, context, function(result, key, value) { - (_.has(result, key) ? result[key] : (result[key] = [])).push(value); - }); - }; - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = function(obj, value, context) { - return group(obj, value, context, function(result, key, value) { - if (!_.has(result, key)) result[key] = 0; - result[key]++; - }); - }; - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iterator, context) { - iterator = iterator == null ? _.identity : lookupIterator(iterator); - var value = iterator.call(context, obj); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >>> 1; - iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; - } - return low; - }; - - // Safely convert anything iterable into a real, live array. - _.toArray = function(obj) { - if (!obj) return []; - if (obj.length === +obj.length) return slice.call(obj); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if ((n != null) && !guard) { - return slice.call(array, Math.max(array.length - n, 0)); - } else { - return array[array.length - 1]; - } - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, (n == null) || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, function(value){ return !!value; }); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, output) { - each(input, function(value) { - if (_.isArray(value)) { - shallow ? push.apply(output, value) : flatten(value, shallow, output); - } else { - output.push(value); - } - }); - return output; - }; - - // Return a completely flattened version of an array. - _.flatten = function(array, shallow) { - return flatten(array, shallow, []); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iterator, context) { - var initial = iterator ? _.map(array, iterator, context) : array; - var results = []; - var seen = []; - each(initial, function(value, index) { - if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { - seen.push(value); - results.push(array[index]); - } - }); - return results; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(concat.apply(ArrayProto, arguments)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; - }); - }); - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); - return _.filter(array, function(value){ return !_.contains(rest, value); }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - var args = slice.call(arguments); - var length = _.max(_.pluck(args, 'length')); - var results = new Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(args, "" + i); - } - return results; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - var result = {}; - for (var i = 0, l = list.length; i < l; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, l = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); - for (; i < l; i++) if (array[i] === item) return i; - return -1; - }; - - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var hasIndex = from != null; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { - return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); - } - var i = (hasIndex ? from : array.length); - while (i--) if (array[i] === item) return i; - return -1; - }; - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; - - var len = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(len); - - while(idx < len) { - range[idx++] = start; - start += step; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Reusable constructor function for prototype setting. - var ctor = function(){}; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Binding with arguments is also known as `curry`. - // Delegates to **ECMAScript 5**'s native `Function.bind` if available. - // We check for `func.bind` first, to fail fast when `func` is undefined. - _.bind = function bind(func, context) { - var bound, args; - if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - if (!_.isFunction(func)) throw new TypeError; - args = slice.call(arguments, 2); - return bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - ctor.prototype = func.prototype; - var self = new ctor; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (Object(result) === result) return result; - return self; - }; - }; - - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length == 0) funcs = _.functions(obj); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. - _.throttle = function(func, wait) { - var context, args, timeout, throttling, more, result; - var whenDone = _.debounce(function(){ more = throttling = false; }, wait); - return function() { - context = this; args = arguments; - var later = function() { - timeout = null; - if (more) { - result = func.apply(context, args); - } - whenDone(); - }; - if (!timeout) timeout = setTimeout(later, wait); - if (throttling) { - more = true; - } else { - throttling = true; - result = func.apply(context, args); - } - whenDone(); - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) result = func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(context, args); - return result; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - memo = func.apply(this, arguments); - func = null; - return memo; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return function() { - var args = [func]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - if (times <= 0) return func(); - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var values = []; - for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); - return values; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var pairs = []; - for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - each(slice.call(arguments, 1), function(source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - }); - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - each(keys, function(key) { - if (key in obj) copy[key] = obj[key]; - }); - return copy; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - for (var key in obj) { - if (!_.contains(keys, key)) copy[key] = obj[key]; - } - return copy; - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - for (var prop in source) { - if (obj[prop] == null) obj[prop] = source[prop]; - } - }); - return obj; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. - if (a === b) return a !== 0 || 1 / a == 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className != toString.call(b)) return false; - switch (className) { - // Strings, numbers, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a == +b; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; - } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] == a) return bStack[length] == b; - } - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && - _.isFunction(bCtor) && (bCtor instanceof bCtor))) { - return false; - } - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, [], []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - return obj === Object(obj); - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) == '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; - } - - // Optimize `isFunction` if appropriate. - if (typeof (/./) !== 'function') { - _.isFunction = function(obj) { - return typeof obj === 'function'; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return _.isNumber(obj) && isFinite(obj); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj != +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iterators. - _.identity = function(value) { - return value; - }; - - // Run a function **n** times. - _.times = function(n, iterator, context) { - for (var i = 0; i < n; i++) iterator.call(context, i); - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + (0 | Math.random() * (max - min + 1)); - }; - - // List of HTML entities for escaping. - var entityMap = { - escape: { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/' - } - }; - entityMap.unescape = _.invert(entityMap.escape); - - // Regexes containing the keys and values listed immediately above. - var entityRegexes = { - escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), - unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') - }; - - // Functions for escaping and unescaping strings to/from HTML interpolation. - _.each(['escape', 'unescape'], function(method) { - _[method] = function(string) { - if (string == null) return ''; - return ('' + string).replace(entityRegexes[method], function(match) { - return entityMap[method][match]; - }); - }; - }); - - // If the value of the named property is a function then invoke it; - // otherwise, return it. - _.result = function(object, property) { - if (object == null) return null; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - each(_.functions(obj), function(name){ - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result.call(this, func.apply(_, args)); - }; - }); - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = idCounter++; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = new RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset) - .replace(escaper, function(match) { return '\\' + escapes[match]; }); - source += - escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" : - interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" : - evaluate ? "';\n" + evaluate + "\n__p+='" : ''; - index = offset + match.length; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + "return __p;\n"; - - try { - var render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled function source as a convenience for precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); - }; - }); - - _.extend(_.prototype, { - - // Start chaining a wrapped Underscore object. - chain: function() { - this._chain = true; - return this; - }, - - // Extracts the result from a wrapped and chained object. - value: function() { - return this._wrapped; - } - - }); - -}).call(this); diff --git a/rsc/scripts/jsdoc/node_modules/wrench/LICENSE b/rsc/scripts/jsdoc/node_modules/wrench/LICENSE deleted file mode 100644 index a85a94a6..00000000 --- a/rsc/scripts/jsdoc/node_modules/wrench/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2010 Ryan McGrath - -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. diff --git a/rsc/scripts/jsdoc/node_modules/wrench/lib/wrench.js b/rsc/scripts/jsdoc/node_modules/wrench/lib/wrench.js deleted file mode 100644 index 00f4166b..00000000 --- a/rsc/scripts/jsdoc/node_modules/wrench/lib/wrench.js +++ /dev/null @@ -1,399 +0,0 @@ -/* wrench.js - * - * A collection of various utility functions I've found myself in need of - * for use with Node.js (http://nodejs.org/). This includes things like: - * - * - Recursively deleting directories in Node.js (Sync, not Async) - * - Recursively copying directories in Node.js (Sync, not Async) - * - Recursively chmoding a directory structure from Node.js (Sync, not Async) - * - Other things that I'll add here as time goes on. Shhhh... - * - * ~ Ryan McGrath (ryan [at] venodesigns.net) - */ - -var fs = require("fs"), - _path = require("path"); - - -/* wrench.readdirSyncRecursive("directory_path"); - * - * Recursively dives through directories and read the contents of all the - * children directories. - */ -exports.readdirSyncRecursive = function(baseDir) { - baseDir = baseDir.replace(/\/$/, ''); - - var readdirSyncRecursive = function(baseDir) { - var files = [], - curFiles, - nextDirs, - isDir = function(fname){ - return fs.statSync( _path.join(baseDir, fname) ).isDirectory(); - }, - prependBaseDir = function(fname){ - return _path.join(baseDir, fname); - }; - - curFiles = fs.readdirSync(baseDir); - nextDirs = curFiles.filter(isDir); - curFiles = curFiles.map(prependBaseDir); - - files = files.concat( curFiles ); - - while (nextDirs.length) { - files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) ); - } - - return files; - }; - - // convert absolute paths to relative - var fileList = readdirSyncRecursive(baseDir).map(function(val){ - return _path.relative(baseDir, val); - }); - - return fileList; -}; - -/* wrench.readdirRecursive("directory_path", function(error, files) {}); - * - * Recursively dives through directories and read the contents of all the - * children directories. - * - * Asynchronous, so returns results/error in callback. - * Callback receives the of files in currently recursed directory. - * When no more directories are left, callback is called with null for all arguments. - * - */ -exports.readdirRecursive = function(baseDir, fn) { - baseDir = baseDir.replace(/\/$/, ''); - - var waitCount = 0; - - function readdirRecursive(curDir) { - var files = [], - curFiles, - nextDirs, - prependcurDir = function(fname){ - return _path.join(curDir, fname); - }; - - waitCount++; - fs.readdir(curDir, function(e, curFiles) { - waitCount--; - - curFiles = curFiles.map(prependcurDir); - - curFiles.forEach(function(it) { - waitCount++; - - fs.stat(it, function(e, stat) { - waitCount--; - - if (e) { - fn(e); - } else { - if (stat.isDirectory()) { - readdirRecursive(it); - } - } - - if (waitCount == 0) { - fn(null, null); - } - }); - }); - - fn(null, curFiles.map(function(val) { - // convert absolute paths to relative - return _path.relative(baseDir, val); - })); - - if (waitCount == 0) { - fn(null, null); - } - }); - }; - - readdirRecursive(baseDir); -}; - - - -/* wrench.rmdirSyncRecursive("directory_path", forceDelete, failSilent); - * - * Recursively dives through directories and obliterates everything about it. This is a - * Sync-function, which blocks things until it's done. No idea why anybody would want an - * Asynchronous version. :\ - */ -exports.rmdirSyncRecursive = function(path, failSilent) { - var files; - - try { - files = fs.readdirSync(path); - } catch (err) { - if(failSilent) return; - throw new Error(err.message); - } - - /* Loop through and delete everything in the sub-tree after checking it */ - for(var i = 0; i < files.length; i++) { - var currFile = fs.lstatSync(path + "/" + files[i]); - - if(currFile.isDirectory()) // Recursive function back to the beginning - exports.rmdirSyncRecursive(path + "/" + files[i]); - - else if(currFile.isSymbolicLink()) // Unlink symlinks - fs.unlinkSync(path + "/" + files[i]); - - else // Assume it's a file - perhaps a try/catch belongs here? - fs.unlinkSync(path + "/" + files[i]); - } - - /* Now that we know everything in the sub-tree has been deleted, we can delete the main - directory. Huzzah for the shopkeep. */ - return fs.rmdirSync(path); -}; - -/* wrench.copyDirSyncRecursive("directory_to_copy", "new_directory_location", opts); - * - * Recursively dives through a directory and moves all its files to a new location. This is a - * Synchronous function, which blocks things until it's done. If you need/want to do this in - * an Asynchronous manner, look at wrench.copyDirRecursively() below. - * - * Note: Directories should be passed to this function without a trailing slash. - */ -exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) { - - if (!opts || !opts.preserve) { - try { - if(fs.statSync(newDirLocation).isDirectory()) exports.rmdirSyncRecursive(newDirLocation); - } catch(e) { } - } - - /* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */ - var checkDir = fs.statSync(sourceDir); - try { - fs.mkdirSync(newDirLocation, checkDir.mode); - } catch (e) { - //if the directory already exists, that's okay - if (e.code !== 'EEXIST') throw e; - } - - var files = fs.readdirSync(sourceDir); - - for(var i = 0; i < files.length; i++) { - var currFile = fs.lstatSync(sourceDir + "/" + files[i]); - - if(currFile.isDirectory()) { - /* recursion this thing right on back. */ - exports.copyDirSyncRecursive(sourceDir + "/" + files[i], newDirLocation + "/" + files[i], opts); - } else if(currFile.isSymbolicLink()) { - var symlinkFull = fs.readlinkSync(sourceDir + "/" + files[i]); - fs.symlinkSync(symlinkFull, newDirLocation + "/" + files[i]); - } else { - /* At this point, we've hit a file actually worth copying... so copy it on over. */ - var contents = fs.readFileSync(sourceDir + "/" + files[i]); - fs.writeFileSync(newDirLocation + "/" + files[i], contents); - } - } -}; - -/* wrench.chmodSyncRecursive("directory", filemode); - * - * Recursively dives through a directory and chmods everything to the desired mode. This is a - * Synchronous function, which blocks things until it's done. - * - * Note: Directories should be passed to this function without a trailing slash. - */ -exports.chmodSyncRecursive = function(sourceDir, filemode) { - var files = fs.readdirSync(sourceDir); - - for(var i = 0; i < files.length; i++) { - var currFile = fs.lstatSync(sourceDir + "/" + files[i]); - - if(currFile.isDirectory()) { - /* ...and recursion this thing right on back. */ - exports.chmodSyncRecursive(sourceDir + "/" + files[i], filemode); - } else { - /* At this point, we've hit a file actually worth copying... so copy it on over. */ - fs.chmod(sourceDir + "/" + files[i], filemode); - } - } - - /* Finally, chmod the parent directory */ - fs.chmod(sourceDir, filemode); -}; - - -/* wrench.chownSyncRecursive("directory", uid, gid); - * - * Recursively dives through a directory and chowns everything to the desired user and group. This is a - * Synchronous function, which blocks things until it's done. - * - * Note: Directories should be passed to this function without a trailing slash. - */ -exports.chownSyncRecursive = function(sourceDir, uid, gid) { - var files = fs.readdirSync(sourceDir); - - for(var i = 0; i < files.length; i++) { - var currFile = fs.lstatSync(sourceDir + "/" + files[i]); - - if(currFile.isDirectory()) { - /* ...and recursion this thing right on back. */ - exports.chownSyncRecursive(sourceDir + "/" + files[i], uid, gid); - } else { - /* At this point, we've hit a file actually worth chowning... so own it. */ - fs.chownSync(sourceDir + "/" + files[i], uid, gid); - } - } - - /* Finally, chown the parent directory */ - fs.chownSync(sourceDir, uid, gid); -}; - - - -/* wrench.rmdirRecursive("directory_path", callback); - * - * Recursively dives through directories and obliterates everything about it. - */ -exports.rmdirRecursive = function rmdirRecursive(dir, clbk){ - fs.readdir(dir, function(err, files){ - if (err) return clbk(err); - (function rmFile(err){ - if (err) return clbk(err); - - var filename = files.shift(); - if (filename === null || typeof filename == 'undefined') - return fs.rmdir(dir, clbk); - - var file = dir+'/'+filename; - fs.stat(file, function(err, stat){ - if (err) return clbk(err); - if (stat.isDirectory()) - rmdirRecursive(file, rmFile); - else - fs.unlink(file, rmFile); - }); - })(); - }); -}; - -/* wrench.copyDirRecursive("directory_to_copy", "new_location", callback); - * - * Recursively dives through a directory and moves all its files to a new - * location. - * - * Note: Directories should be passed to this function without a trailing slash. - */ -exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, clbk) { - fs.stat(newDir, function(err, newDirStat){ - if (!err) return exports.rmdirRecursive(newDir, function(err){ - copyDirRecursive(srcDir, newDir, clbk); - }); - - fs.stat(srcDir, function(err, srcDirStat){ - if (err) return clbk(err); - fs.mkdir(newDir, srcDirStat.mode, function(err){ - if (err) return clbk(err); - fs.readdir(srcDir, function(err, files){ - if (err) return clbk(err); - (function copyFiles(err){ - if (err) return clbk(err); - - var filename = files.shift(); - if (filename === null || typeof filename == 'undefined') - return clbk(); - - var file = srcDir+'/'+filename, - newFile = newDir+'/'+filename; - - fs.stat(file, function(err, fileStat){ - if (fileStat.isDirectory()) - copyDirRecursive(file, newFile, copyFiles); - else if (fileStat.isSymbolicLink()) - fs.readlink(file, function(err, link){ - fs.symlink(link, newFile, copyFiles); - }); - else - fs.readFile(file, function(err, data){ - fs.writeFile(newFile, data, copyFiles); - }); - }); - })(); - }); - }); - }); - }); -}; - -var mkdirSyncRecursive = function(path, mode) { - var self = this; - - try { - fs.mkdirSync(path, mode); - } catch(err) { - if(err.code == "ENOENT") { - var slashIdx = path.lastIndexOf("/"); - if(slashIdx < 0) { - slashIdx = path.lastIndexOf("\\"); - } - - if(slashIdx > 0) { - var parentPath = path.substring(0, slashIdx); - mkdirSyncRecursive(parentPath, mode); - mkdirSyncRecursive(path, mode); - } else { - throw err; - } - } else if(err.code == "EEXIST") { - return; - } else { - throw err; - } - } -}; -exports.mkdirSyncRecursive = mkdirSyncRecursive; - -exports.LineReader = function(filename, bufferSize) { - this.bufferSize = bufferSize || 8192; - this.buffer = ""; - this.fd = fs.openSync(filename, "r"); - this.currentPosition = 0; -}; - -exports.LineReader.prototype = { - getBufferAndSetCurrentPosition: function(position) { - var res = fs.readSync(this.fd, this.bufferSize, position, "ascii"); - - this.buffer += res[0]; - if(res[1] === 0) { - this.currentPosition = -1; - } else { - this.currentPosition = position + res[1]; - } - - return this.currentPosition; - }, - - hasNextLine: function() { - while(this.buffer.indexOf('\n') === -1) { - this.getBufferAndSetCurrentPosition(this.currentPosition); - if(this.currentPosition === -1) return false; - } - - if(this.buffer.indexOf("\n") > -1) return true; - return false; - }, - - getNextLine: function() { - var lineEnd = this.buffer.indexOf("\n"), - result = this.buffer.substring(0, lineEnd); - - this.buffer = this.buffer.substring(result.length + 1, this.buffer.length); - return result; - } -}; - -// vim: et ts=4 sw=4 diff --git a/rsc/scripts/jsdoc/node_modules/wrench/package.json b/rsc/scripts/jsdoc/node_modules/wrench/package.json deleted file mode 100644 index 7c426e76..00000000 --- a/rsc/scripts/jsdoc/node_modules/wrench/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "wrench", - "description": "Recursive filesystem (and other) operations that Node *should* have.", - "version": "1.3.9", - "author": { - "name": "Ryan McGrath", - "email": "ryan@venodesigns.net" - }, - "repository": { - "type": "git", - "url": "https://ryanmcgrath@github.com/ryanmcgrath/wrench-js.git" - }, - "bugs": { - "url": "http://github.com/ryanmcgrath/wrench-js/issues" - }, - "directories": { - "lib": "./lib/" - }, - "dependencies": {}, - "devDependencies": { - "nodeunit": ">= 0.6.4" - }, - "main": "./lib/wrench", - "engines": { - "node": ">=0.1.97" - }, - "scripts": { - "test": "nodeunit tests/runner.js" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/ryanmcgrath/wrench-js/raw/master/LICENSE" - } - ], - "readme": "wrench.js - Recursive file operations in Node.js\n----------------------------------------------------------------------------\nWhile I love Node.js, I've found myself missing some functions. Things like\nrecursively deleting/chmodding a directory (or even deep copying a directory),\nor even a basic line reader, shouldn't need to be re-invented time and time again.\n\nThat said, here's my attempt at a re-usable solution, at least until something\nmore formalized gets integrated into Node.js (*hint hint*). wrench.js is fairly simple\nto use - check out the documentation/examples below:\n\nInstallation\n-----------------------------------------------------------------------------\n\n npm install wrench\n\nUsage\n-----------------------------------------------------------------------------\n``` javascript\nvar wrench = require('wrench'),\n\tutil = require('util');\n```\n\n### Synchronous operations\n``` javascript\n// Recursively create directories, sub-trees and all.\nwrench.mkdirSyncRecursive(dir, 0777);\n\n// Recursively delete the entire sub-tree of a directory, then kill the directory\nwrench.rmdirSyncRecursive('my_directory_name', failSilently);\n\n// Recursively read directories contents.\nwrench.readdirSyncRecursive('my_directory_name');\n\n// Recursively chmod the entire sub-tree of a directory\nwrench.chmodSyncRecursive('my_directory_name', 0755);\n\n// Recursively chown the entire sub-tree of a directory\nwrench.chownSyncRecursive(\"directory\", uid, gid);\n\n// Deep-copy an existing directory\nwrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');\n\n// Read lines in from a file until you hit the end\nvar f = new wrench.LineReader('x.txt');\nwhile(f.hasNextLine()) {\n\tutil.puts(x.getNextLine());\n}\n```\n\n### Asynchronous operations\n``` javascript\n// Recursively read directories contents\nvar files = [];\nwrench.readdirRecursive('my_directory_name', function(error, curFiles) {\n // curFiles is what you want\n});\n\n```\n\nQuestions, comments? Hit me up. (ryan [at] venodesigns.net | http://twitter.com/ryanmcgrath)\n", - "_id": "wrench@1.3.9", - "_from": "wrench" -} diff --git a/rsc/scripts/jsdoc/nodejs/bin/jsdoc b/rsc/scripts/jsdoc/nodejs/bin/jsdoc deleted file mode 100644 index c53efc4d..00000000 --- a/rsc/scripts/jsdoc/nodejs/bin/jsdoc +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env node - -// This wrapper script allows JSDoc to be installed with 'npm install -g'. -// Note that JSDoc will still run on Mozilla Rhino, NOT Node.js. - - -var fs = require('fs'); -var os = require('os'); -var path = require('path'); -var spawnProc = require('child_process').spawn; - -var args = process.argv.slice(2); -var script = path.normalize( path.join( path.dirname(fs.realpathSync(process.argv[1])), '..', '..', - 'jsdoc' ) ); -var jsdoc; - -if (process.platform === 'win32') { - jsdoc = spawnProc(script + '.cmd', args, {stdio: 'inherit'}); -} -else { - jsdoc = spawnProc(script, args, {stdio: 'inherit'}); -} - -jsdoc.on('close', function(code) { - process.exit(code); -}); diff --git a/rsc/scripts/jsdoc/nodejs/jsdoc/fs.js b/rsc/scripts/jsdoc/nodejs/jsdoc/fs.js deleted file mode 100644 index 7115ff0c..00000000 --- a/rsc/scripts/jsdoc/nodejs/jsdoc/fs.js +++ /dev/null @@ -1,17 +0,0 @@ -var e = ' is not implemented for Node.js!'; - -exports.ls = function() { - throw new Error('fs.ls' + e); -}; - -exports.toDir = function() { - throw new Error('fs.toDir' + e); -}; - -exports.mkPath = function() { - throw new Error('fs.mkpath' + e); -}; - -exports.copyFileSync = function() { - throw new Error('fs.copyFileSync' + e); -}; diff --git a/rsc/scripts/jsdoc/nodejs/jsdoc/util/include.js b/rsc/scripts/jsdoc/nodejs/jsdoc/util/include.js deleted file mode 100644 index c5c0d4de..00000000 --- a/rsc/scripts/jsdoc/nodejs/jsdoc/util/include.js +++ /dev/null @@ -1,8 +0,0 @@ -// TODO: not tested -module.exports = function(filepath) { - var fs = require('jsdoc/fs'); - var vm = require('vm'); - - var script = fs.readFileSync(filepath, 'utf8'); - vm.runInNewContext(script, global, filepath); -}; diff --git a/rsc/scripts/jsdoc/out/app.html b/rsc/scripts/jsdoc/out/app.html deleted file mode 100644 index 70224fc1..00000000 --- a/rsc/scripts/jsdoc/out/app.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - JSDoc: Namespace: app - - - - - - - - - - -
    - -

    Namespace: app

    - - - - - -
    - -
    -

    - app -

    - -
    - -
    -
    - - - - -
    Data that must be shared across the entire application.
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - -
    - - - - - - - - - - - - - - - - - - -
    - -
    - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:10 GMT+0300 (EEST) -
    - - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/out/env.html b/rsc/scripts/jsdoc/out/env.html deleted file mode 100644 index 49789891..00000000 --- a/rsc/scripts/jsdoc/out/env.html +++ /dev/null @@ -1,441 +0,0 @@ - - - - - JSDoc: Namespace: env - - - - - - - - - - -
    - -

    Namespace: env

    - - - - - -
    - -
    -

    - env -

    - -
    - -
    -
    - - - - -
    Data representing the environment in which this app is running.
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - -
    - - - - - - - - - - - - -

    Members

    - -
    - -
    -

    <static> args :Array

    - - -
    -
    - -
    - The command-line arguments passed into JSDoc. -
    - - - -
    Type:
    -
      -
    • - -Array - - -
    • -
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    <static> conf :Object

    - - -
    -
    - -
    - The parsed JSON data from the configuration file. -
    - - - -
    Type:
    -
      -
    • - -Object - - -
    • -
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    <static> opts :Object

    - - -
    -
    - -
    - The command-line arguments, parsed into a key/value hash. -
    - - - -
    Type:
    -
      -
    • - -Object - - -
    • -
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    Example
    - -
     if (env.opts.help) { console.log('Helpful message.'); }
    - - -
    - - - -
    -

    <static> run

    - - -
    -
    - -
    - Running start and finish times. -
    - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    <static> version :Object

    - - -
    -
    - -
    - The JSDoc version number and revision date. -
    - - - -
    Type:
    -
      -
    • - -Object - - -
    • -
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - -
    - - - - - - - -
    - -
    - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:10 GMT+0300 (EEST) -
    - - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/out/functions..html b/rsc/scripts/jsdoc/out/functions..html deleted file mode 100644 index 57c46574..00000000 --- a/rsc/scripts/jsdoc/out/functions..html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - JSDoc: Namespace: General javascript functions. - - - - - - - - - - -
    - -

    Namespace: General javascript functions.

    - - - - - -
    - -
    -

    - General javascript functions. -

    - -
    - -
    -
    - - - - -
    This file contains the Genral Functions javascript namespace. -It contains functions that apply both on the front and back -end of the application.
    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - -
    - - - - - - - - - - - - - - - - - - -
    - -
    - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:22:10 GMT+0300 (EEST) -
    - - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/out/general_functions.js.html b/rsc/scripts/jsdoc/out/general_functions.js.html deleted file mode 100644 index f52c1b0a..00000000 --- a/rsc/scripts/jsdoc/out/general_functions.js.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - JSDoc: Source: general_functions.js - - - - - - - - - - -
    - -

    Source: general_functions.js

    - - - - - -
    -
    -
    /**
    - * This file contains the Genral Functions javascript namespace.
    - * It contains functions that apply both on the front and back 
    - * end of the application.
    - * 
    - * @namespace General javascript functions.
    - */
    -var GeneralFunctions = {};
    -
    -/**
    - * This functions displays a message box in
    - * the admin array. It is usefull when user
    - * decisions or verifications are needed.
    - *  
    - * @param {string} title The title of the message box.
    - * @param {string} message The message of the dialog.
    - * @param {array} messageButtons Contains the dialog  
    - * buttons along with their functions.
    - */
    -GeneralFunctions.displayMessageBox = function(title, message, messageButtons) {
    -    // Check arguments integrity.
    -    if (title == undefined || title == "") {
    -        title = "<No Title Given>";
    -    }   
    -        
    -    if (message == undefined || message == "") {
    -        message = "<No Message Given>";
    -    } 
    -    
    -    if (messageButtons == undefined) {
    -        messageButtons = {
    -            Close: function() {
    -                jQuery("#message_box").dialog("close");
    -            }
    -        };
    -    }
    -    
    -    // Destroy previous dialog instances.
    -    jQuery("#message_box").dialog("destroy");
    -    jQuery("#message_box").remove();
    -    
    -    // Create the html of the message box.
    -    jQuery("body").append(
    -        "<div id='message_box' title='" + title + "'>" +
    -        "<p>" + message + "</p>" +
    -        "</div>"
    -    );    
    -
    -    jQuery("#message_box").dialog({
    -        autoOpen        : false,
    -        modal           : true,
    -        resize          : "auto",
    -        width           : 400,
    -        height          : "auto",
    -        resizable       : false,
    -        buttons         : messageButtons,
    -        closeOnEscape   : false
    -    });
    -    
    -    jQuery("#message_box").dialog("open"); 
    -    jQuery("#message_box .ui-dialog-titlebar-close").hide();
    -}
    -
    -/**
    - * This method centers a DOM element vertically and horizontally
    - * on the page.
    - * 
    - * @param {object} elementHandle The object that is going to be 
    - * centered.
    - */
    -GeneralFunctions.centerElementOnPage = function(elementHandle) {
    -    // Center main frame vertical middle
    -    $(window).resize(function() {
    -        var elementLeft = ($(window).width() - elementHandle.outerWidth()) / 2;
    -        var elementTop = ($(window).height() - elementHandle.outerHeight()) / 2;
    -        elementTop = (elementTop > 0 ) ? elementTop : 20;
    -        
    -        elementHandle.css({
    -            position    : 'absolute',
    -            left        : elementLeft,
    -            top         : elementTop
    -        }); 
    -    });
    -    $(window).resize();
    -}
    -
    -
    - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:22:10 GMT+0300 (EEST) -
    - - - - - diff --git a/rsc/scripts/jsdoc/out/global.html b/rsc/scripts/jsdoc/out/global.html deleted file mode 100644 index 874eef5c..00000000 --- a/rsc/scripts/jsdoc/out/global.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - JSDoc: Global - - - - - - - - - - -
    - -

    Global

    - - - - - -
    - -
    -

    - -

    - -
    - -
    -
    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - -
    - - - - - - - - - - - - - - -

    Methods

    - -
    - -
    -

    main()

    - - -
    -
    - - -
    - Run the jsdoc application. -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    To Do:
    -
    -
      -
    • Refactor function (and require statements) into smaller functions
    • -
    -
    - -
    - - - - - - - - - - - - - -
    - -
    - - - - - -
    - -
    - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:10 GMT+0300 (EEST) -
    - - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/out/index.html b/rsc/scripts/jsdoc/out/index.html deleted file mode 100644 index af89af85..00000000 --- a/rsc/scripts/jsdoc/out/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - JSDoc: Index - - - - - - - - - - -
    - -

    Index

    - - - - - - - -

    - - - - - - - - - - - - - - - - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:22:10 GMT+0300 (EEST) -
    - - - - - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/out/jsdoc.js.html b/rsc/scripts/jsdoc/out/jsdoc.js.html deleted file mode 100644 index c8b3fb7d..00000000 --- a/rsc/scripts/jsdoc/out/jsdoc.js.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - JSDoc: Source: jsdoc.js - - - - - - - - - - -
    - -

    Source: jsdoc.js

    - - - - - -
    -
    -
    /*global app: true, args: true, env: true, publish: true */
    -/**
    - * @project jsdoc
    - * @author Michael Mathews <micmath@gmail.com>
    - * @license See LICENSE.md file included in this distribution.
    - */
    -
    -// try: $ java -classpath build-files/java/classes/js.jar org.mozilla.javascript.tools.shell.Main main.js `pwd` script/to/parse.js
    -
    -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    -
    -/**
    - * Data representing the environment in which this app is running.
    - *
    - * @namespace
    - * @name env
    - */
    -require('lib/jsdoc/util/global').env = {
    -    /**
    -     * Running start and finish times.
    -     * 
    -     * @memberof env
    -     */
    -    run: {
    -        start: new Date(),
    -        finish: null
    -    },
    -
    -    /**
    -     * The command-line arguments passed into JSDoc.
    -     *
    -     * @type Array
    -     * @memberof env
    -     */
    -    args: [],
    -
    -    /**
    -     * The parsed JSON data from the configuration file.
    -     * 
    -     * @type Object
    -     * @memberof env
    -     */
    -    conf: {},
    -
    -    /**
    -     * The absolute path to the base directory of the JSDoc application.
    -     * 
    -     * @private
    -     * @deprecated Use `__dirname` instead.
    -     * @type string
    -     * @memberof env
    -     */
    -    dirname: '.',
    -
    -    /**
    -     * The command-line arguments, parsed into a key/value hash.
    -     * 
    -     * @type Object
    -     * @memberof env
    -     * @example if (env.opts.help) { console.log('Helpful message.'); }
    -    */
    -    opts: {},
    -
    -    /**
    -     * The JSDoc version number and revision date.
    -     * 
    -     * @type Object
    -     * @memberof env
    -     */
    -    version: {}
    -};
    -
    -// initialize the environment for the current JavaScript VM
    -(function(args) {
    -    var vm = require('jsdoc/util/vm').vm;
    -    // TODO: may need to move this file to support Node.js
    -    require('initialize')[vm](args);
    -})( Array.prototype.slice.call(arguments, 0) );
    -
    -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    -
    -/**
    - * Data that must be shared across the entire application.
    - * @namespace
    - * @name app
    - */
    -require('lib/jsdoc/util/global').app = {
    -    jsdoc: {
    -        scanner: new (require('jsdoc/src/scanner').Scanner)(),
    -        parser: new (require('jsdoc/src/parser').Parser)(),
    -        name: require('jsdoc/name')
    -    }
    -};
    -
    -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    -
    -/**
    -    Try to recursively print out all key/values in an object.
    -    @global
    -    @private
    -    @param {Object} ... Object/s to dump out to console.
    - */
    -function dump() {
    -    var doop = require('jsdoc/util/doop').doop;
    -    var _dump = require('jsdoc/util/dumper').dump;
    -    for (var i = 0, l = arguments.length; i < l; i++) {
    -        console.log( _dump(doop(arguments[i])) );
    -    }
    -}
    -
    -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    -
    -/**
    - * Run the jsdoc application.
    - * @todo Refactor function (and require statements) into smaller functions
    - */
    -function main() {
    -    var _ = require('underscore');
    -    var fs = require('jsdoc/fs');
    -    var path = require('jsdoc/path');
    -    var taffy = require('taffydb').taffy;
    -
    -    var jsdoc = {
    -        augment: require('jsdoc/augment'),
    -        borrow: require('jsdoc/borrow'),
    -        Config: require('jsdoc/config'),
    -        opts: {
    -            args: require('jsdoc/opts/args')
    -        },
    -        'package': require('jsdoc/package'),
    -        plugins: require('jsdoc/plugins'),
    -        Readme: require('jsdoc/readme'),
    -        src: {
    -            filter: require('jsdoc/src/filter'),
    -            handlers: require('jsdoc/src/handlers')
    -        },
    -        tutorial: {
    -            resolver: require('jsdoc/tutorial/resolver')
    -        },
    -        util: {
    -            include: require('jsdoc/util/include')
    -        }
    -    };
    -
    -    var confPath;
    -    var defaultOpts;
    -    var docs;
    -    var filter;
    -    var i;
    -    var info;
    -    var l;
    -    var packageDocs;
    -    var packageJson;
    -    var sourceFiles;
    -    var template;
    -
    -
    -    defaultOpts = {
    -        destination: './out/',
    -        encoding: 'utf8'
    -    };
    -
    -    // get JSDoc version number
    -    info = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
    -    env.version = {
    -        number: info.version,
    -        revision: new Date(parseInt(info.revision, 10)).toUTCString()
    -    };
    -
    -    env.opts = jsdoc.opts.args.parse(env.args);
    -
    -    confPath = env.opts.configure || path.join(__dirname, 'conf.json');
    -    if ( !fs.statSync(confPath).isFile() ) {
    -        confPath = path.join(__dirname, 'conf.json.EXAMPLE');
    -    }
    -
    -    try {
    -        env.conf = new jsdoc.Config( fs.readFileSync(confPath, 'utf8') )
    -            .get();
    -    }
    -    catch (e) {
    -        throw new Error('Cannot parse the config file ' + confPath + ': ' + e);
    -    }
    -
    -    // look for options on the command line, in the config file, and in the defaults, in that order
    -    env.opts = _.defaults(env.opts, env.conf.opts, defaultOpts);
    -
    -    if (env.opts.help) {
    -        console.log( jsdoc.opts.args.help() );
    -        process.exit(0);
    -    } else if (env.opts.test) {
    -        jsdoc.util.include('test/runner.js');
    -        process.exit(0);
    -    } else if (env.opts.version) {
    -        console.log('JSDoc ' + env.version.number + ' (' + env.version.revision + ')');
    -        process.exit(0);
    -    }
    -
    -    if (env.conf.plugins) {
    -        jsdoc.plugins.installPlugins(env.conf.plugins, app.jsdoc.parser);
    -    }
    -    
    -    if (env.conf.source && env.conf.source.include) {
    -        env.opts._ = (env.opts._ || []).concat(env.conf.source.include);
    -    }
    -
    -    // any source file named package.json or README.md is treated special
    -    for (i = 0, l = env.opts._.length; i < l; i++ ) {
    -        if (/\bpackage\.json$/i.test(env.opts._[i])) {
    -            packageJson = fs.readFileSync( env.opts._[i], 'utf8' );
    -            env.opts._.splice(i--, 1);
    -        }
    -        
    -        if (/(\bREADME|\.md)$/i.test(env.opts._[i])) {
    -            env.opts.readme = new jsdoc.Readme(env.opts._[i]).html;
    -            env.opts._.splice(i--, 1);
    -        }
    -    }
    -    
    -    if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse?
    -        filter = new jsdoc.src.filter.Filter(env.conf.source);
    -
    -        sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), filter);
    -
    -        jsdoc.src.handlers.attachTo(app.jsdoc.parser);
    -
    -        docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding);
    -
    -        //The files are ALWAYS useful for the templates to have
    -        //If there is no package.json, just create an empty package
    -        packageDocs = new jsdoc.package.Package(packageJson);
    -        packageDocs.files = sourceFiles || [];
    -        docs.push(packageDocs);
    -
    -        jsdoc.borrow.indexAll(docs);
    -
    -        jsdoc.augment.addInherited(docs);
    -        jsdoc.borrow.resolveBorrows(docs);
    -
    -        if (env.opts.explain) {
    -            dump(docs);
    -            process.exit(0);
    -        }
    -
    -        if (env.opts.tutorials) {
    -            jsdoc.tutorial.resolver.load(env.opts.tutorials);
    -            jsdoc.tutorial.resolver.resolve();
    -        }
    -
    -        env.opts.template = (function() {
    -            var publish = env.opts.template || 'templates/default';
    -            // if we don't find it, keep the user-specified value so the error message is useful
    -            return path.getResourcePath(publish) || env.opts.template;
    -        })();
    -
    -        try {
    -            template = require(env.opts.template + '/publish');
    -        }
    -        catch(e) {
    -            throw new Error('Unable to load template: ' + e.message || e);
    -        }
    -
    -        // templates should include a publish.js file that exports a "publish" function
    -        if (template.publish && typeof template.publish === 'function') {
    -            // convert this from a URI back to a path if necessary
    -            env.opts.template = path._uriToPath(env.opts.template);
    -            template.publish(
    -                taffy(docs),
    -                env.opts,
    -                jsdoc.tutorial.resolver.root
    -            );
    -        }
    -        else {
    -            // old templates define a global "publish" function, which is deprecated
    -            jsdoc.util.include(env.opts.template + '/publish.js');
    -            if (publish && typeof publish === 'function') {
    -                console.log( env.opts.template + ' uses a global "publish" function, which is ' +
    -                    'deprecated and may not be supported in future versions. ' +
    -                    'Please update the template to use "exports.publish" instead.' );
    -                // convert this from a URI back to a path if necessary
    -                env.opts.template = path._uriToPath(env.opts.template);
    -                publish(
    -                    taffy(docs),
    -                    env.opts,
    -                    jsdoc.tutorial.resolver.root
    -                );
    -            }
    -            else {
    -                throw new Error( env.opts.template + ' does not export a "publish" function.' );
    -            }
    -        }
    -    }
    -}
    -
    -try {
    -    main();
    -    env.run.finish = new Date();
    -    process.exit(0);
    -}
    -catch(e) {
    -    env.run.finish = new Date();
    -    if (e.rhinoException != null) {
    -        e.rhinoException.printStackTrace();
    -        process.exit(1);
    -    } else {
    -        throw e;
    -    }
    -}
    -
    -
    -
    - - - - -
    - - - -
    - -
    - Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 17:20:10 GMT+0300 (EEST) -
    - - - - - diff --git a/rsc/scripts/jsdoc/out/scripts/linenumber.js b/rsc/scripts/jsdoc/out/scripts/linenumber.js deleted file mode 100644 index a0c570d5..00000000 --- a/rsc/scripts/jsdoc/out/scripts/linenumber.js +++ /dev/null @@ -1,17 +0,0 @@ -(function() { - var counter = 0; - var numbered; - var source = document.getElementsByClassName('prettyprint source'); - - if (source && source[0]) { - source = source[0].getElementsByTagName('code')[0]; - - numbered = source.innerHTML.split('\n'); - numbered = numbered.map(function(item) { - counter++; - return '' + item; - }); - - source.innerHTML = numbered.join('\n'); - } -})(); diff --git a/rsc/scripts/jsdoc/out/scripts/prettify/Apache-License-2.0.txt b/rsc/scripts/jsdoc/out/scripts/prettify/Apache-License-2.0.txt deleted file mode 100644 index d6456956..00000000 --- a/rsc/scripts/jsdoc/out/scripts/prettify/Apache-License-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/rsc/scripts/jsdoc/out/scripts/prettify/lang-css.js b/rsc/scripts/jsdoc/out/scripts/prettify/lang-css.js deleted file mode 100644 index 041e1f59..00000000 --- a/rsc/scripts/jsdoc/out/scripts/prettify/lang-css.js +++ /dev/null @@ -1,2 +0,0 @@ -PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", -/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/rsc/scripts/jsdoc/out/scripts/prettify/prettify.js b/rsc/scripts/jsdoc/out/scripts/prettify/prettify.js deleted file mode 100644 index eef5ad7e..00000000 --- a/rsc/scripts/jsdoc/out/scripts/prettify/prettify.js +++ /dev/null @@ -1,28 +0,0 @@ -var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; -(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= -[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), -l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, -q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, -q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, -"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), -a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} -for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], -"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], -H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], -J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ -I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), -["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", -/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), -["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", -hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= -!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p - }) - .synonym('throws'); -2. lookUp(title) - Used to lookup a tag. Returns either the tag or false if it's not defined -3. isNamespace(kind) - Used to determine if a particular doclet type represents a namespace -4. normalise(title) - Used to find the canonical name of a tag. The name passed in might be that - name or a synonym - -### Node Visitors - -At the lowest level, plugin authors can process each node in the parse tree by -defining a node visitor that will visit each node, creating an opportunity to -do things like modify comments and trigger parser events for any arbitrary piece -of code. - -Plugins can define a node visitor by exporting a ```nodeVisitor``` object that -contains a ```visitNode``` function, like so: - - exports.nodeVisitor = { - visitNode: function(node, e, parser, currentSourceName) { - //do all sorts of crazy things here - } - } - -The function is called on each node with the following parameters: - -- node: the node of the parse tree -- e: the event. If the node is one that the parser handles, this will already - be populated with the same things described in the _symbolFound_ event above. - Otherwise, it will be an empty object on which to set various properties. -- parser: the parser -- currentSourceName: the name of the file being parsed - -#### Making things happen - -The primary reasons to implement a node visitor are to be able to document -things that aren't normally documented (like function calls that create classes) -or to auto generate documentation for code that isn't documented. For instance, -a plugin might look for calls to a "_trigger" method since it knows that means -an event is fired and then generate documentation for the event. - -To make things happen, the ```visitNode``` function should modify properties -of the event parameter. In general the goal is to construct a comment and then -get an event to fire. After the parser lets all of the node visitors have a -look at the node, it looks to see if the event object has a ```comment``` -property and an ```event``` property. If it has both, the event named in the event -property is fired. The event is usually "symbolFound" or "jsdocCommentFound", -but theoretically, a plugin could define its own events and handle them. - -#### Example - -Below is an example of what a plugin for documenting jQuery UI widgets might do. -jQuery UI uses a factory function call to create widget classes. The plugin -looks for that function call and creates a symbol with documentation. It also -looks for any "this._trigger" function calls and automatically creates -documentation for the events that are triggered: - - exports.nodeVisitor = { - visitNode: function(node, e, parser, currentSourceName) { - if (node.type === Token.OBJECTLIT && node.parent && node.parent.type === Token.CALL && isInWidgetFactory(node, 1)) { - var widgetName = node.parent.arguments.get(0).toSource(); - e.id = 'astnode' + node.hashCode(); // the id of the object literal node - e.comment = String(node.parent.jsDoc||''); - e.lineno = node.parent.getLineno(); - e.filename = currentSourceName; - e.astnode = node; - e.code = { - name: "" + widgetName.substring(1, widgetName.length() - 1), - type: "class", - node: node - }; - e.event = "symbolFound"; - e.finishers = [parser.addDocletRef]; - - addCommentTag(e, "param", "{Object=} options A set of configuration options"); - } - else if(isTriggerCall(node)) { - var nameNode = node.arguments.get(0); - eventName = String((nameNode.type == Token.STRING) ? nameNode.value : nameNode.toSource()), - func = {}, - comment = "@event\n", - eventKey = ""; - - if (node.enclosingFunction) { - func.id = 'astnode'+node.enclosingFunction.hashCode(); - func.doclet = parser.refs[func.id]; - } - if(func.doclet) { - func.doclet.addTag("fires", eventName); - if (func.doclet.memberof) { - eventKey = func.doclet.memberof + "#event:" + eventName; - comment += "@name " + func.doclet.memberof + "#" + eventName; - } - } - e.comment = comment; - e.lineno = node.getLineno(); - e.filename = currentSourceName; - e.event = "jsdocCommentFound"; - } - } - }; - function isTriggerCall(node) { - if(node.type != Token.CALL) { return false; } - var target = node.getTarget(), - left = target && target.left && String(target.left.toSource()), - right = target && target.right && String(target.right.toSource()); - return (left === "this" && right === "_trigger"); - } - - function isInWidgetFactory(node, depth) { - var parent = node.parent, - d = 0; - while(parent && (!depth || d < depth)) { - if (parent.type === Token.CALL) { - var target = parent.getTarget(), - left = target && target.left && String(target.left.toSource()), - right = target && target.right && String(target.right.toSource()); - return ((left === "$" || left === "jQuery") && right === "widget"); - } else { - parent = parent.parent; - d++; - } - } - return false; - } - -You'll notice a "finishers" property set. The finishers property should contain -an array of functions to be called after the event is fired and all the handlers -have processed it. The parser provides an ```addDocletRef``` function that adds the -doclet to the map (keyed off of the id property) of doclets it knows about. - -Lastly, the visitors are executed in the order the plugins are listed in the -conf.json file. A plugin can stop later plugins from visiting a node by -setting a ```stopPropagation``` property on the event object (e.stopPropagation = true). -A plugin can stop the event from firing setting a ```preventDefault``` property. - -### Throwing Errors - -If you wish your plugin to throw an error, do it using the `handle` function in -the `jsdoc/util/error` module: - - require('jsdoc/util/error').handle( new Error('I do not like green eggs and ham!') ); - -By default, this will throw the error, halting the execution of JSDoc. However, -if the user enabled JSDoc's `--lenient` switch, JSDoc will simply log the error -to the console and continue. - -Packaging JSDoc 3 Plugins ----- - -The JSDoc 3 Jakefile has an ```install``` task that can be used to install a -plugin into the JSDoc directory. So running the following will install the -plugin: - - $>jake install[path/to/YourPluginFolder] - -**Note**: On some operating systems, including OS X, you may need to quote the -target name and parameters: - - $>jake 'install[path/to/YourPluginFolder]' - -The task is passed a directory that should look something like the following: - - YourPluginFolder - |- plugins - | |- YourPlugin.js - | \- test - | |- fixtures - | | \- YourFixtures.js - | \- specs - | \- YourTests.js - \- templates - \- YourTemplate - \- publish.js diff --git a/rsc/scripts/jsdoc/plugins/commentConvert.js b/rsc/scripts/jsdoc/plugins/commentConvert.js deleted file mode 100644 index 244c3313..00000000 --- a/rsc/scripts/jsdoc/plugins/commentConvert.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - @overview Demonstrate how to modify the source code before the parser sees it. - @module plugins/commentConvert - @author Michael Mathews - */ - - -exports.handlers = { - /// - /// Convert ///-style comments into jsdoc comments. - /// @param e - /// @param e.filename - /// @param e.source - /// - beforeParse: function(e) { - e.source = e.source.replace(/(\n[ \t]*\/\/\/[^\n]*)+/g, function($) { - var replacement = '\n/**' + $.replace(/^[ \t]*\/\/\//mg, '').replace(/(\n$|$)/, '*/$1'); - return replacement; - }); - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/commentsOnly.js b/rsc/scripts/jsdoc/plugins/commentsOnly.js deleted file mode 100644 index e5106e9f..00000000 --- a/rsc/scripts/jsdoc/plugins/commentsOnly.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @overview Remove everything in a file except JSDoc-style comments. By enabling this plugin, you - * can document source files that are not valid JavaScript (including source files for other - * languages). - * @module plugins/commentsOnly - * @author Jeff Williams - */ - -exports.handlers = { - beforeParse: function(e) { - // a JSDoc comment looks like: /**[one or more chars]*/ - var comments = e.source.match(/\/\*\*[\s\S]+?\*\//g); - if (comments) { - e.source = comments.join('\n\n'); - } - } -}; diff --git a/rsc/scripts/jsdoc/plugins/escapeHtml.js b/rsc/scripts/jsdoc/plugins/escapeHtml.js deleted file mode 100644 index d77c2629..00000000 --- a/rsc/scripts/jsdoc/plugins/escapeHtml.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - @overview Escape HTML tags in descriptions. - @module plugins/escapeHtml - @author Michael Mathews - */ - - -exports.handlers = { - /** - Translate HTML tags in descriptions into safe entities. - Replaces <, & and newlines - */ - newDoclet: function(e) { - if (e.doclet.description) { - e.doclet.description = e.doclet.description - .replace(/&/g,'&') - .replace(/'); - } - } -}; diff --git a/rsc/scripts/jsdoc/plugins/eventDumper.js b/rsc/scripts/jsdoc/plugins/eventDumper.js deleted file mode 100644 index 70eff028..00000000 --- a/rsc/scripts/jsdoc/plugins/eventDumper.js +++ /dev/null @@ -1,69 +0,0 @@ -/*global env: true */ -/** - * @overview Dump information about parser events to the console. - * @module plugins/eventDumper - * @author Jeff Williams - */ - -var _ = require('underscore'); -var util = require('util'); - -var conf = env.conf.eventDumper || {}; - -// Dump the included parser events (defaults to all events) -var events = conf.include || [ - 'parseBegin', - 'fileBegin', - 'beforeParse', - 'jsdocCommentFound', - 'symbolFound', - 'newDoclet', - 'fileComplete', - 'parseComplete' -]; -// Don't dump the excluded parser events -if (conf.exclude) { - events = _.difference(events, conf.exclude); -} - -/** - * Get rid of native Java crud in an event object so that JSON.stringify() works. - * @param {object} e The event object. - * @return {object} The fixed-up object. - */ -function cleanse(e) { - var result = {}; - - Object.keys(e).forEach(function(prop) { - // by default, don't stringify properties that contain an array of functions - if (!conf.includeFunctions && util.isArray(e[prop]) && e[prop][0] && - String(typeof e[prop][0]) === 'function') { - result[prop] = 'function[' + e[prop].length + ']'; - } - // never include functions that belong to the object - else if (typeof e[prop] === 'function') { - // do nothing - } - // go down an extra level for these - else if (['code', 'doclet', 'meta'].indexOf(prop) !== -1) { - result[prop] = cleanse(e[prop]); - } - else { - result[prop] = String(e[prop]); - } - }); - - return result; -} - - -exports.handlers = {}; - -events.forEach(function(eventType) { - exports.handlers[eventType] = function(e) { - console.log( JSON.stringify({ - type: eventType, - content: cleanse(e) - }, null, 4) ); - }; -}); diff --git a/rsc/scripts/jsdoc/plugins/markdown.js b/rsc/scripts/jsdoc/plugins/markdown.js deleted file mode 100644 index 0ec29ae5..00000000 --- a/rsc/scripts/jsdoc/plugins/markdown.js +++ /dev/null @@ -1,67 +0,0 @@ -/*global env: true */ -/** - * @overview Translate doclet descriptions from MarkDown into HTML. - * @module plugins/markdown - * @author Michael Mathews - * @author Ben Blank - */ -var conf = env.conf.markdown; -var defaultTags = [ "classdesc", "description", "params", "properties", "returns", "see"]; -var hasOwnProp = Object.prototype.hasOwnProperty; -var parse = require('jsdoc/util/markdown').getParser(); -var tags = []; -var excludeTags = []; - -/** - * Process the markdown source in a doclet. The properties that should be - * processed are configurable, but always include "classdesc", "description", - * "params", "properties", and "returns". Handled properties can be bare - * strings, objects, or arrays of objects. - */ -function process(doclet) { - tags.forEach(function(tag) { - if ( !hasOwnProp.call(doclet, tag) ) { - return; - } - - if (typeof doclet[tag] === "string" && - (tag != 'see' || - // treat '@see' specially, since we only want to process @see text that contains links - (tag == 'see' && doclet[tag].indexOf('[') != -1))) { - doclet[tag] = parse(doclet[tag]); - } else if (doclet[tag] instanceof Array) { - doclet[tag].forEach(function(value, index, original){ - var inner = {}; - inner[tag] = value; - process(inner); - original[index] = inner[tag]; - }); - } else if (doclet[tag]) { - process(doclet[tag]); - } - }); -} - -// set up the list of "tags" (properties) to process -if (conf && conf.tags) { - tags = conf.tags.slice(); -} -// set up the list of default tags to exclude from processing -if (conf && conf.excludeTags) { - excludeTags = conf.excludeTags.slice(); -} -defaultTags.forEach(function(tag) { - if (excludeTags.indexOf(tag) === -1 && tags.indexOf(tag) === -1) { - tags.push(tag); - } -}); - -exports.handlers = { - /** - * Translate markdown syntax in a new doclet's description into HTML. Is run - * by JSDoc 3 whenever a "newDoclet" event fires. - */ - newDoclet: function(e) { - process(e.doclet); - } -}; diff --git a/rsc/scripts/jsdoc/plugins/markdown.md b/rsc/scripts/jsdoc/plugins/markdown.md deleted file mode 100644 index 578d751e..00000000 --- a/rsc/scripts/jsdoc/plugins/markdown.md +++ /dev/null @@ -1,86 +0,0 @@ -# How to use the Markdown plugin - -For most users, all you need to do is add the plugin to your JSDoc configuration (`conf.json`) as you would any other, by adding a reference to the plugin in the `"plugins"` entry: - - ... - "plugins": [ "plugins/markdown" ] - ... - -This will cause Markdown in `@description` tags (including implicit descriptions without tags), `@classdesc` tags, `@param` tags, `@property` tags, and `@returns` tags to be parsed. - -Also, be sure to use leading asterisks in your doc comments! If you omit the leading asterisks, JSDoc's code parser may remove other asterisks that are used for Markdown formatting. - -# Configuring the Markdown plugin - -The plugin also offers several configuration options for advanced users who want GitHub integration, extended tag support, etc. All configuration for the Markdown plugin should be added to a `"markdown"` property in your JSDoc configuration: - - ... - "plugins": [ "plugins/markdown" ], - - "markdown": { - "opt1": "value", - "opt2": [ "foo", "bar", "baz" ] - } - ... - -## Choosing a parser - -The plugin currently supports two Markdown parsers. You can select which parser to use by adding a `"parser"` property to your Markdown configuration: - - ... - "plugins": [ "plugins/markdown" ], - - "markdown": { - "parser": "gfm" - } - ... - -### Dominic "evilstreak" Baggott's markdown-js - -The default parser is Dominic Baggott's excellent [markdown-js](https://github.com/evilstreak/markdown-js). It can be explicitly selected by setting the `parser` to `evilstreak` and has one additional (and optional) configuration option, `dialect`, which can be used to select which of markdown-js' built-in dialects to use. If omitted, markdown-js' default dialect will be used. - - ... - "plugins": [ "plugins/markdown" ], - - "markdown": { - "parser": "evilstreak", - "dialect": "Maruku" - } - ... - -### GitHib Flavored Markdown - -The alternative parser is the modified Showdown parser supplied by GitHub for their [GitHub Flavored Markdown](http://github.github.com/github-flavored-markdown/). GFM provides several enhancements to standard Markdown syntax (see its documentation) intended to be useful to developers. It *also* has the ability to quickly link to GitHub repositories, files, and issues. It can be selected by setting the `parser` to `gfm` and supports three additional (and optional) configuration options. - -The `hardwrap` option controls the hard wrapping of line ends. Unlike standard Markdown, GFM considers a single newline to indicate a "hard break" in the paragraph, but this doesn't work well with the line length limitations commonly used with comment documentation, so is disabled by default. If you want to turn hard wrapping back on, set `hardwrap` to `true` (or any non-falsy value). - -The `githubRepoName` and `githubRepoOwner` indicate which GitHub repo should be used for GitHub links that do not fully specify a repo. These options have no effect unless used together, and if they are omitted, several of GFM's default link types will be unavailable. Conversely, if you supply both `github*` options but do not explicitly select `gfm` as your parser, it will be automatically selected for you. - - ... - "plugins": [ "plugins/markdown" ], - - "markdown": { - "parser": "gfm", - "hardwrap": true - } - ... - -### Why two parsers? - -The "evilstreak" parser is flexible, extensible, currently maintained, and was the only parser available in earlier versions of the Markdown plugin, but doesn't support the useful GFM extensions. The "gfm" parser is based on the no-longer-maintained Showdown parser, but it provides GFM extensions. - -In the future, if GFM support is made available for the "evilstreak" parser, this plugin will drop the "gfm" parser in favor of that support. - -## Extended tag support - -While the Markdown plugin already supports JSDoc's default tags, if you're using other plugins, you may well have extra tags available. You can tell the Markdown plugin to handle those extra tags as well using the `tags` property, which is an array of the tags* it should check in addition to the default set. - - ... - "plugins": [ "plugins/markdown" ], - - "markdown": { - "tags": [ "foo", "bars", "bazzes" ] - } - ... - -\* Because the Markdown plugin works with JSDoc's internal representation rather than with the source comments, the names you need to enter in the `tags` property aren't necessarily the same as the actual tag names. For example, in the default set of tags, `@param` is stored under `params`. If you are having trouble getting the Markdown plugin to work with your extra tags, either take a peek at the output of JSDoc's `--explain` command-line parameter (which displays the internal state that plugins work with) or ask the plugin author which "doclet properties" their plugin uses. The Markdown plugin supports strings, arrays, and objects/subdoclets. diff --git a/rsc/scripts/jsdoc/plugins/overloadHelper.js b/rsc/scripts/jsdoc/plugins/overloadHelper.js deleted file mode 100644 index 35fe3213..00000000 --- a/rsc/scripts/jsdoc/plugins/overloadHelper.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - * The Overload Helper plugin automatically adds a signature-like string to the longnames of - * overloaded functions and methods. In JSDoc, this string is known as a _variation_. (The longnames - * of overloaded constructor functions are _not_ updated, so that JSDoc can identify the class' - * members correctly.) - * - * Using this plugin allows you to link to overloaded functions without manually adding `@variation` - * tags to your documentation. - * - * For example, suppose your code includes a function named `foo` that you can call in the - * following ways: - * - * + `foo()` - * + `foo(bar)` - * + `foo(bar, baz)` (where `baz` is repeatable) - * - * This plugin assigns the following variations and longnames to each version of `foo`: - * - * + `foo()` gets the variation `()` and the longname `foo()`. - * + `foo(bar)` gets the variation `(bar)` and the longname `foo(bar)`. - * + `foo(bar, baz)` (where `baz` is repeatable) gets the variation `(bar, ...baz)` and the longname - * `foo(bar, ...baz)`. - * - * You can then link to these functions with `{@link foo()}`, `{@link foo(bar)}`, and - * `{@link foo(bar, ...baz)`. Note that the variation is based on the names of the function - * parameters, _not_ their types. - * - * If you prefer to manually assign variations to certain functions, you can still do so with the - * `@variation` tag. This plugin will not change these variations or add more variations for that - * function, as long as the variations you've defined result in unique longnames. - * - * If an overloaded function includes multiple signatures with the same parameter names, the plugin - * will assign numeric variations instead, starting at `(1)` and counting upwards. - * - * @module plugins/overloadHelper - * @author Jeff Williams - * @license Apache License 2.0 - */ - -// lookup table of function doclets by longname -var functionDoclets; - -function hasUniqueValues(obj) { - var isUnique = true; - var seen = []; - Object.keys(obj).forEach(function(key) { - if (seen.indexOf(obj[key]) !== -1) { - isUnique = false; - } - - seen.push(obj[key]); - }); - - return isUnique; -} - -function getParamNames(params) { - var names = []; - - params.forEach(function(param) { - var name = param.name || ''; - if (param.variable) { - name = '...' + name; - } - if (name !== '') { - names.push(name); - } - }); - - return names.length ? names.join(', ') : ''; -} - -function getParamVariation(doclet) { - return getParamNames(doclet.params || []); -} - -function getUniqueVariations(doclets) { - var counter = 0; - var variations = {}; - var docletKeys = Object.keys(doclets); - - function getUniqueNumbers() { - var format = require('util').format; - - docletKeys.forEach(function(doclet) { - var newLongname; - - while (true) { - counter++; - variations[doclet] = String(counter); - - // is this longname + variation unique? - newLongname = format('%s(%s)', doclets[doclet].longname, variations[doclet]); - if ( !functionDoclets[newLongname] ) { - break; - } - } - }); - } - - function getUniqueNames() { - // start by trying to preserve existing variations - docletKeys.forEach(function(doclet) { - variations[doclet] = doclets[doclet].variation || getParamVariation(doclets[doclet]); - }); - - // if they're identical, try again, without preserving existing variations - if ( !hasUniqueValues(variations) ) { - docletKeys.forEach(function(doclet) { - variations[doclet] = getParamVariation(doclets[doclet]); - }); - - // if they're STILL identical, switch to numeric variations - if ( !hasUniqueValues(variations) ) { - getUniqueNumbers(); - } - } - } - - // are we already using numeric variations? if so, keep doing that - if (functionDoclets[doclets.newDoclet.longname + '(1)']) { - getUniqueNumbers(); - } - else { - getUniqueNames(); - } - - return variations; -} - -function ensureUniqueLongname(newDoclet) { - var doclets = { - oldDoclet: functionDoclets[newDoclet.longname], - newDoclet: newDoclet - }; - var docletKeys = Object.keys(doclets); - var oldDocletLongname; - var variations = {}; - - if (doclets.oldDoclet) { - oldDocletLongname = doclets.oldDoclet.longname; - // if the shared longname has a variation, like MyClass#myLongname(variation), - // remove the variation - if (doclets.oldDoclet.variation || doclets.oldDoclet.variation === '') { - docletKeys.forEach(function(doclet) { - doclets[doclet].longname = doclets[doclet].longname.replace(/\([\s\S]*\)$/, ''); - doclets[doclet].variation = null; - }); - } - - variations = getUniqueVariations(doclets); - - // update the longnames/variations - docletKeys.forEach(function(doclet) { - doclets[doclet].longname += '(' + variations[doclet] + ')'; - doclets[doclet].variation = variations[doclet]; - }); - - // update the old doclet in the lookup table - functionDoclets[oldDocletLongname] = null; - functionDoclets[doclets.oldDoclet.longname] = doclets.oldDoclet; - } - - // always store the new doclet in the lookup table - functionDoclets[doclets.newDoclet.longname] = doclets.newDoclet; - - return doclets.newDoclet; -} - -exports.handlers = { - parseBegin: function() { - functionDoclets = {}; - }, - - newDoclet: function(e) { - if (e.doclet.kind === 'function') { - e.doclet = ensureUniqueLongname(e.doclet); - } - }, - - parseComplete: function() { - functionDoclets = null; - } -}; diff --git a/rsc/scripts/jsdoc/plugins/partial.js b/rsc/scripts/jsdoc/plugins/partial.js deleted file mode 100644 index 61d20d26..00000000 --- a/rsc/scripts/jsdoc/plugins/partial.js +++ /dev/null @@ -1,31 +0,0 @@ -/*global env: true */ -/** - @overview Adds support for reusable partial jsdoc files. - @module plugins/partial - @author Ludo Antonov - */ - -var fs = require('jsdoc/fs'); -var path = require('path'); - -exports.handlers = { - /// - /// Include a partial jsdoc - /// @param e - /// @param e.filename - /// @param e.source - /// - /// @example - /// @partial "partial_doc.jsdoc" - /// - beforeParse: function(e) { - e.source = e.source.replace(/(@partial \".*\")+/g, function($) { - var pathArg = $.match(/\".*\"/)[0].replace(/"/g,''); - var fullPath = path.join(e.filename , '..', pathArg); - - var partialData = fs.readFileSync(fullPath, env.opts.encoding); - - return partialData; - }); - } -}; diff --git a/rsc/scripts/jsdoc/plugins/railsTemplate.js b/rsc/scripts/jsdoc/plugins/railsTemplate.js deleted file mode 100644 index 9ca63098..00000000 --- a/rsc/scripts/jsdoc/plugins/railsTemplate.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - @overview Strips the rails template tags from a js.erb file - @module plugins/railsTemplate - @author Jannon Frank - */ - - -exports.handlers = { - /** - * Remove rails tags from the source input (e.g. <% foo bar %>) - * @param e - * @param e.filename - * @param e.source - */ - beforeParse: function(e) { - if (e.filename.match(/\.erb$/)) { - e.source = e.source.replace(/<%.*%>/g, ""); - } - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/shout.js b/rsc/scripts/jsdoc/plugins/shout.js deleted file mode 100644 index bb9c2c5d..00000000 --- a/rsc/scripts/jsdoc/plugins/shout.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - @overview This is just an example. - @module plugins/shout - @author Michael Mathews - */ - -exports.handlers = { - /** - Make your descriptions more shoutier. - */ - newDoclet: function(e) { - if (typeof e.doclet.description === 'string') { - e.doclet.description = e.doclet.description.toUpperCase(); - } - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/sourcetag.js b/rsc/scripts/jsdoc/plugins/sourcetag.js deleted file mode 100644 index efde8e0a..00000000 --- a/rsc/scripts/jsdoc/plugins/sourcetag.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - @module plugins/sourcetag - @author Michael Mathews - */ - -exports.handlers = { - /** - Support @source tag. Expected value like: - { "filename": "myfile.js", "lineno": 123 } - Modifies the corresponding meta values on the given doclet. - @source { "filename": "sourcetag.js", "lineno": 13 } - */ - newDoclet: function(e) { - var tags = e.doclet.tags, - tag, - value; - - //console.log(e.doclet); - // any user-defined tags in this doclet? - if (typeof tags !== 'undefined') { - // only interested in the @source tags - tags = tags.filter(function($) { - return $.title === 'source'; - }); - - if (tags.length) { - // take the first one - tag = tags[0]; - - try { - value = JSON.parse(tag.value); - } - catch(e) { - throw new Error('@source tag expects a valid JSON value, like { "filename": "myfile.js", "lineno": 123 }.'); - } - - e.doclet.meta = e.doclet.meta || {}; - e.doclet.meta.filename = value.filename || ''; - e.doclet.meta.lineno = value.lineno || ''; - } - } - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/test/fixtures/overloadHelper.js b/rsc/scripts/jsdoc/plugins/test/fixtures/overloadHelper.js deleted file mode 100644 index 12c298c6..00000000 --- a/rsc/scripts/jsdoc/plugins/test/fixtures/overloadHelper.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * A bowl of non-spicy soup. - * @class - *//** - * A bowl of spicy soup. - * @class - * @param {number} spiciness - The spiciness of the soup, in Scoville heat units (SHU). - */ -function Soup(spiciness) {} - -/** - * Slurp the soup. - *//** - * Slurp the soup loudly. - * @param {number} dBA - The slurping volume, in A-weighted decibels. - */ -Soup.prototype.slurp = function(dBA) {}; - -/** - * Salt the soup as needed, using a highly optimized soup-salting heuristic. - *//** - * Salt the soup, specifying the amount of salt to add. - * @variation mg - * @param {number} amount - The amount of salt to add, in milligrams. - */ -Soup.prototype.salt = function(amount) {}; - -/** - * Heat the soup by the specified number of degrees. - * @param {number} degrees - The number of degrees, in Fahrenheit, by which to heat the soup. - *//** - * Heat the soup by the specified number of degrees. - * @variation 1 - * @param {string} degrees - The number of degrees, in Fahrenheit, by which to heat the soup, but - * as a string for some reason. - *//** - * Heat the soup by the specified number of degrees. - * @param {boolean} degrees - The number of degrees, as a boolean. Wait, what? - */ -Soup.prototype.heat = function(degrees) {}; - -/** - * Discard the soup. - * @variation discardSoup - *//** - * Discard the soup by pouring it into the specified container. - * @variation discardSoup - * @param {Object} container - The container in which to discard the soup. - */ -Soup.prototype.discard = function(container) {}; diff --git a/rsc/scripts/jsdoc/plugins/test/fixtures/railsTemplate.js.erb b/rsc/scripts/jsdoc/plugins/test/fixtures/railsTemplate.js.erb deleted file mode 100644 index 446aa409..00000000 --- a/rsc/scripts/jsdoc/plugins/test/fixtures/railsTemplate.js.erb +++ /dev/null @@ -1,20 +0,0 @@ -/** - @overview Strips the rails template tags from a js.erb file - @module plugins/railsTemplate - @author Jannon Frank - */ - - -exports.handlers = { - /** - * Remove rails tags from the source input (e.g. <% foo bar %>) - * @param e - * @param e.filename - * @param e.source - */ - beforeParse: function(e) { - if (e.filename.match(/\.erb$/)) { - e.source = e.source.replace(/<%.*%> /g, ""); - } - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/test/fixtures/seetag-markdown.js b/rsc/scripts/jsdoc/plugins/test/fixtures/seetag-markdown.js deleted file mode 100644 index 57137616..00000000 --- a/rsc/scripts/jsdoc/plugins/test/fixtures/seetag-markdown.js +++ /dev/null @@ -1,12 +0,0 @@ -/** -* @see [Nowhere](http://nowhere.com) -*/ -function foo() { -} - -/** -* @see AnObject#myProperty -*/ -function bar() { -} - diff --git a/rsc/scripts/jsdoc/plugins/test/specs/commentConvert.js b/rsc/scripts/jsdoc/plugins/test/specs/commentConvert.js deleted file mode 100644 index 3f1dc08c..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/commentConvert.js +++ /dev/null @@ -1,14 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("commentConvert plugin", function() { - var parser = new (require("jsdoc/src/parser")).Parser(), - plugin = require('plugins/commentConvert'), - docSet; - - require('jsdoc/plugins').installPlugins(['plugins/commentConvert'], parser); - docSet = jasmine.getDocSetFromFile("plugins/commentConvert.js", parser); - - it("should convert '///-style comments into jsdoc comments", function() { - var doclet = docSet.getByLongname("module:plugins/commentConvert.handlers.beforeParse"); - expect(doclet.length).toEqual(1); - }); -}); diff --git a/rsc/scripts/jsdoc/plugins/test/specs/escapeHtml.js b/rsc/scripts/jsdoc/plugins/test/specs/escapeHtml.js deleted file mode 100644 index 8bd88210..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/escapeHtml.js +++ /dev/null @@ -1,14 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("escapeHtml plugin", function() { - var parser = new (require("jsdoc/src/parser")).Parser(), - plugin = require('plugins/escapeHtml'), - docSet; - - require('jsdoc/plugins').installPlugins(['plugins/escapeHtml'], parser); - docSet = jasmine.getDocSetFromFile("plugins/escapeHtml.js", parser); - - it("should escape '&', '<' and newlines in doclet descriptions", function() { - var doclet = docSet.getByLongname("module:plugins/escapeHtml.handlers.newDoclet"); - expect(doclet[0].description).toEqual("Translate HTML tags in descriptions into safe entities.
    Replaces <, & and newlines"); - }); -}); diff --git a/rsc/scripts/jsdoc/plugins/test/specs/markdown.js b/rsc/scripts/jsdoc/plugins/test/specs/markdown.js deleted file mode 100644 index ce08324f..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/markdown.js +++ /dev/null @@ -1,22 +0,0 @@ -describe("markdown plugin", function() { - //TODO -}); - -describe("markdown see tag support", function() { - var plugin = require('plugins/markdown'), - docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/seetag-markdown.js'), - foo = docSet.getByLongname('foo')[0], - bar = docSet.getByLongname('bar')[0]; - - it ('should parse @see tags containing links', function() { - plugin.handlers.newDoclet({doclet:foo}); - expect(typeof foo).toEqual('object'); - expect(foo.see[0]).toEqual('

    Nowhere

    '); - }) - - it ('should not parse @see tags that do not contain links', function() { - plugin.handlers.newDoclet({doclet:bar}); - expect(typeof bar).toEqual('object'); - expect(bar.see[0]).toEqual('AnObject#myProperty'); - }) -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/test/specs/overloadHelper.js b/rsc/scripts/jsdoc/plugins/test/specs/overloadHelper.js deleted file mode 100644 index c57d2130..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/overloadHelper.js +++ /dev/null @@ -1,96 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true, xit: true */ -describe('plugins/overloadHelper', function() { - var parser = new (require('jsdoc/src/parser')).Parser(); - var plugin = require('plugins/overloadHelper'); - var docSet; - - require('jsdoc/plugins').installPlugins(['plugins/overloadHelper'], parser); - docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser); - - it('should exist', function() { - expect(plugin).toBeDefined(); - expect(typeof plugin).toBe('object'); - }); - - it('should export handlers', function() { - expect(plugin.handlers).toBeDefined(); - expect(typeof plugin.handlers).toBe('object'); - }); - - it('should export a "newDoclet" handler', function() { - expect(plugin.handlers.newDoclet).toBeDefined(); - expect(typeof plugin.handlers.newDoclet).toBe('function'); - }); - - it('should export a "parseComplete" handler', function() { - expect(plugin.handlers.parseComplete).toBeDefined(); - expect(typeof plugin.handlers.parseComplete).toBe('function'); - }); - - describe('newDoclet handler', function() { - it('should not add unique longnames to constructors', function() { - var soup = docSet.getByLongname('Soup'); - var soup1 = docSet.getByLongname('Soup()'); - var soup2 = docSet.getByLongname('Soup(spiciness)'); - - expect(soup.length).toBe(2); - expect(soup1.length).toBe(0); - expect(soup2.length).toBe(0); - }); - - it('should add unique longnames to methods', function() { - var slurp = docSet.getByLongname('Soup#slurp'); - var slurp1 = docSet.getByLongname('Soup#slurp()'); - var slurp2 = docSet.getByLongname('Soup#slurp(dBA)'); - - expect(slurp.length).toBe(0); - expect(slurp1.length).toBe(1); - expect(slurp2.length).toBe(1); - }); - - it('should update the "variation" property of the method', function() { - var slurp1 = docSet.getByLongname('Soup#slurp()')[0]; - var slurp2 = docSet.getByLongname('Soup#slurp(dBA)')[0]; - - expect(slurp1.variation).toBe(''); - expect(slurp2.variation).toBe('dBA'); - }); - - it('should not add to or change existing variations that are unique', function() { - var salt1 = docSet.getByLongname('Soup#salt'); - var salt2 = docSet.getByLongname('Soup#salt(mg)'); - - expect(salt1.length).toBe(1); - expect(salt2.length).toBe(1); - }); - - it('should not duplicate the names of existing numeric variations', function() { - var heat1 = docSet.getByLongname('Soup#heat(1)'); - var heat2 = docSet.getByLongname('Soup#heat(2)'); - var heat3 = docSet.getByLongname('Soup#heat(3)'); - - expect(heat1.length).toBe(1); - expect(heat2.length).toBe(1); - expect(heat3.length).toBe(1); - }); - - it('should replace identical variations with new, unique variations', function() { - var discard1 = docSet.getByLongname('Soup#discard()'); - var discard2 = docSet.getByLongname('Soup#discard(container)'); - - expect(discard1.length).toBe(1); - expect(discard2.length).toBe(1); - }); - }); - - describe('parseComplete handler', function() { - // disabled because on the second run, each comment is being parsed twice; who knows why... - xit('should not retain parse results between parser runs', function() { - parser.clear(); - docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser); - var heat = docSet.getByLongname('Soup#heat(4)'); - - expect(heat.length).toBe(0); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/plugins/test/specs/railsTemplate.js b/rsc/scripts/jsdoc/plugins/test/specs/railsTemplate.js deleted file mode 100644 index 2f89ee5a..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/railsTemplate.js +++ /dev/null @@ -1,16 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("railsTemplate plugin", function() { - var parser = new (require("jsdoc/src/parser")).Parser(), - plugin = require('plugins/railsTemplate'); - - - require('jsdoc/plugins').installPlugins(['plugins/railsTemplate'], parser); - require('jsdoc/src/handlers').attachTo(parser); - - it("should remove <% %> rails template tags from the source of *.erb files", function() { - var path = require("path"), - docSet = parser.parse([path.join(__dirname, "plugins/test/fixtures/railsTemplate.js.erb")]); - - expect(docSet[2].description).toEqual("Remove rails tags from the source input (e.g. )"); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/plugins/test/specs/shout.js b/rsc/scripts/jsdoc/plugins/test/specs/shout.js deleted file mode 100644 index 75e70b64..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/shout.js +++ /dev/null @@ -1,14 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("shout plugin", function() { - var parser = new (require("jsdoc/src/parser")).Parser(), - plugin = require('plugins/shout'), - docSet; - - require('jsdoc/plugins').installPlugins(['plugins/shout'], parser); - docSet = jasmine.getDocSetFromFile("plugins/shout.js", parser); - - it("should make the description uppercase", function() { - var doclet = docSet.getByLongname("module:plugins/shout.handlers.newDoclet"); - expect(doclet[0].description).toEqual("MAKE YOUR DESCRIPTIONS MORE SHOUTIER."); - }); -}); diff --git a/rsc/scripts/jsdoc/plugins/test/specs/sourcetag.js b/rsc/scripts/jsdoc/plugins/test/specs/sourcetag.js deleted file mode 100644 index 84d65337..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/sourcetag.js +++ /dev/null @@ -1,16 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("sourcetag plugin", function() { - var parser = new (require("jsdoc/src/parser")).Parser(), - plugin = require('plugins/sourcetag'), - docSet; - - require('jsdoc/plugins').installPlugins(['plugins/sourcetag'], parser); - docSet = jasmine.getDocSetFromFile("plugins/sourcetag.js", parser); - - it("should set the lineno and filename of the doclet's meta property", function() { - var doclet = docSet.getByLongname("module:plugins/sourcetag.handlers.newDoclet"); - expect(doclet[0].meta).toBeDefined(); - expect(doclet[0].meta.filename).toEqual("sourcetag.js"); - expect(doclet[0].meta.lineno).toEqual(13); - }); -}); diff --git a/rsc/scripts/jsdoc/plugins/test/specs/verboseOutput.js b/rsc/scripts/jsdoc/plugins/test/specs/verboseOutput.js deleted file mode 100644 index e8ac43bd..00000000 --- a/rsc/scripts/jsdoc/plugins/test/specs/verboseOutput.js +++ /dev/null @@ -1,19 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true, xit: true */ -/** - * @author Rob Taylor [manix84@gmail.com] - */ - -describe("verbose output plugin", function () { - var parser = new (require("jsdoc/src/parser")).Parser(), - plugin = require('plugins/verboseOutput'), - docSet; - - //require('jsdoc/plugins').installPlugins(['plugins/verboseOutput'], parser); - docSet = jasmine.getDocSetFromFile("plugins/verboseOutput.js", parser); - - xit("should log file names to console", function() { - // TODO: this doesn't actually test the plugin... - var fileBegin = docSet.getByLongname("module:plugins/verboseOutput.handlers.fileBegin"); - expect(fileBegin[0].description).toEqual("Logging the file name to the console."); - }); -}); diff --git a/rsc/scripts/jsdoc/plugins/verboseOutput.js b/rsc/scripts/jsdoc/plugins/verboseOutput.js deleted file mode 100644 index 454a4a05..00000000 --- a/rsc/scripts/jsdoc/plugins/verboseOutput.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Adds a verbose output to the console, so that you can see what's happening in your process. - * @module plugins/verboseOutput - * @author Rob Taylor - The basic idea - * @author Michael Mathews - Wrote the first itteration with me :) - */ - -exports.handlers = { - /** - * Logging the file name to the console. - */ - fileBegin: function (data) { - console.log(data.filename); - } -}; diff --git a/rsc/scripts/jsdoc/rhino/MPL_1.1.txt b/rsc/scripts/jsdoc/rhino/MPL_1.1.txt deleted file mode 100644 index 7714141d..00000000 --- a/rsc/scripts/jsdoc/rhino/MPL_1.1.txt +++ /dev/null @@ -1,470 +0,0 @@ - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (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.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] - diff --git a/rsc/scripts/jsdoc/rhino/crypto.js b/rsc/scripts/jsdoc/rhino/crypto.js deleted file mode 100644 index 487e55cf..00000000 --- a/rsc/scripts/jsdoc/rhino/crypto.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('crypto-browserify'); diff --git a/rsc/scripts/jsdoc/rhino/events.js b/rsc/scripts/jsdoc/rhino/events.js deleted file mode 100644 index 4546adab..00000000 --- a/rsc/scripts/jsdoc/rhino/events.js +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Shim for Node.js `events` module. Adapted from `node-browserify`. - * @see https://github.com/substack/node-browserify - * @license MIT - */ - -if (!process.EventEmitter) { - process.EventEmitter = function () {}; -} - -var EventEmitter = exports.EventEmitter = process.EventEmitter; -var isArray = typeof Array.isArray === 'function' ? - Array.isArray : - function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; - } -; - -// By default EventEmitters will print a warning if more than -// 10 listeners are added to it. This is a useful default which -// helps finding memory leaks. -// -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -var defaultMaxListeners = 10; -EventEmitter.prototype.setMaxListeners = function(n) { - if (!this._events) { - this._events = {}; - } - this._events.maxListeners = n; -}; - - -EventEmitter.prototype.emit = function(type) { - var args; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events || !this._events.error || - (isArray(this._events.error) && !this._events.error.length)) - { - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error("Uncaught, unspecified 'error' event."); - } - return false; - } - } - - if (!this._events) { - return false; - } - var handler = this._events[type]; - if (!handler) { - return false; - } - - if (typeof handler == 'function') { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - return true; - - } else if (isArray(handler)) { - args = Array.prototype.slice.call(arguments, 1); - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { - listeners[i].apply(this, args); - } - return true; - - } else { - return false; - } -}; - -// EventEmitter is defined in src/node_events.cc -// EventEmitter.prototype.emit() is also defined there. -EventEmitter.prototype.addListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('addListener only takes instances of Function'); - } - - if (!this._events) { - this._events = {}; - } - - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); - - if (!this._events[type]) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } else if (isArray(this._events[type])) { - - // Check for listener leak - if (!this._events[type].warned) { - var m; - if (this._events.maxListeners !== undefined) { - m = this._events.maxListeners; - } else { - m = defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - - // If we've already got an array, just append. - this._events[type].push(listener); - } else { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - var self = this; - self.on(type, function g() { - self.removeListener(type, g); - listener.apply(this, arguments); - }); - - return this; -}; - -EventEmitter.prototype.removeListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('removeListener only takes instances of Function'); - } - - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events || !this._events[type]) { - return this; - } - - var list = this._events[type]; - - if (isArray(list)) { - var i = list.indexOf(listener); - if (i < 0) { - return this; - } - list.splice(i, 1); - if (list.length === 0) { - delete this._events[type]; - } - } else if (this._events[type] === listener) { - delete this._events[type]; - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - // does not use listeners(), so no side effect of creating _events[type] - if (type && this._events && this._events[type]) { - this._events[type] = null; - } - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - if (!this._events) { - this._events = {}; - } - if (!this._events[type]) { - this._events[type] = []; - } - if (!isArray(this._events[type])) { - this._events[type] = [this._events[type]]; - } - return this._events[type]; -}; diff --git a/rsc/scripts/jsdoc/rhino/fs.js b/rsc/scripts/jsdoc/rhino/fs.js deleted file mode 100644 index eeb29c6f..00000000 --- a/rsc/scripts/jsdoc/rhino/fs.js +++ /dev/null @@ -1,176 +0,0 @@ -/*global Packages: true */ - -/** - * Partial Rhino shim for Node.js' `fs` module. - * @see http://nodejs.org/api/fs.html - */ - -var path = require('path'); - -var asyncify = path._asyncify; - -function checkEncoding(enc, name) { - // we require the `encoding` parameter for Node.js compatibility; on Node.js, if you omit the - // encoding, you get a stream instead of a string - if (!enc || typeof enc === 'function') { - throw new Error(name + ' requires an encoding on Rhino!'); - } - - // Node.js wants 'utf8', but Java wants 'utf-8' - if (enc === 'utf8') { - enc = 'utf-8'; - } - - return enc; -} - -exports.readFileSync = function(filename, encoding) { - encoding = checkEncoding(encoding, 'fs.readFile[Sync]'); - - return readFile(filename, encoding); -}; -exports.readFile = asyncify(exports.readFileSync); - -// in node 0.8, path.exists() and path.existsSync() moved to the "fs" module -exports.existsSync = path.existsSync; -exports.exists = path.exists; - -var statSync = exports.statSync = function(_path) { - var f = new java.io.File(_path); - return { - isFile: function() { - return f.isFile(); - }, - isDirectory: function() { - return f.isDirectory(); - } - }; -}; -exports.stat = asyncify(statSync); - -var readdirSync = exports.readdirSync = function(_path) { - var dir; - var files; - - dir = new java.io.File(_path); - if (!dir.directory) { - throw new Error("ENOENT, no such file or directory '" + _path + "'"); - } - - files = dir.list(); - - // Convert files to Javascript strings so they play nice with node modules - files = files.map(function(fileName) { - return String(fileName); - }); - - return files; -}; -exports.readdir = asyncify(readdirSync); - -// JSDoc extension to `fs` module -var ls = exports.ls = function(dir, recurse, _allFiles, _path) { - var files, - file; - - if (typeof _path === 'undefined') { // initially - _allFiles = []; - _path = [dir]; - } - - if (_path.length === 0) { return _allFiles; } - if (typeof recurse === 'undefined') { recurse = 1; } - - if ( statSync(dir).isFile(dir) ) { - files = [dir]; - } - else { - files = readdirSync(dir); - } - - for (var f = 0, lenf = files.length; f < lenf; f++) { - file = String(files[f]); - - if (file.match(/^\.[^\.\/\\]/)) { continue; } // skip dot files - - if ((new java.io.File(_path.join('/') + '/' + file)).list()) { // it's a directory - _path.push(file); - - if (_path.length - 1 < recurse) { - ls(_path.join('/'), recurse, _allFiles, _path); - } - _path.pop(); - } - else { // it's a file - _allFiles.push( - path.normalize(_path.join('/') + '/' + file) - ); - } - } - - return _allFiles; -}; - -// JSDoc extension to `fs` module -var toDir = exports.toDir = function(_path) { - var f = new java.io.File(_path); - - if (f.isDirectory()){ - return _path; - } else { - return path.dirname(_path); - } -}; - -var mkdirSync = exports.mkdirSync = function(_path) { - var dir_path = toDir(_path); - (new java.io.File(dir_path)).mkdir(); -}; -exports.mkdir = asyncify(mkdirSync); - -// JSDoc extension to `fs` module -exports.mkPath = function(/**Array*/ _path) { - if (_path.constructor == Array) { _path = _path.join(''); } - - (new java.io.File(_path)).mkdirs(); -}; - -// JSDoc extension to `fs` module -exports.copyFileSync = function(inFile, outDir, fileName) { - if (fileName == null){fileName = path.basename(inFile);} - - outDir = toDir(outDir); - - inFile = new java.io.File(inFile); - var outFile = new java.io.File(outDir+'/'+fileName); - - var bis = new Packages.java.io.BufferedInputStream(new Packages.java.io.FileInputStream(inFile), 4096); - var bos = new Packages.java.io.BufferedOutputStream(new Packages.java.io.FileOutputStream(outFile), 4096); - var theChar; - while ((theChar = bis.read()) != -1) { - bos.write(theChar); - } - bos.close(); - bis.close(); -}; -exports.copyFile = asyncify(exports.copyFileSync); - -exports.writeFileSync = function(filename, data, encoding) { - encoding = checkEncoding(encoding, 'fs.writeFile[Sync]'); - - var out = new Packages.java.io.PrintWriter( - new Packages.java.io.OutputStreamWriter( - new Packages.java.io.FileOutputStream(filename), - encoding - ) - ); - - try { - out.write(data); - } - finally { - out.flush(); - out.close(); - } -}; -exports.writeFile = asyncify(exports.writeFileSync); diff --git a/rsc/scripts/jsdoc/rhino/js.jar b/rsc/scripts/jsdoc/rhino/js.jar deleted file mode 100644 index a6a87eba..00000000 Binary files a/rsc/scripts/jsdoc/rhino/js.jar and /dev/null differ diff --git a/rsc/scripts/jsdoc/rhino/jsdoc.js b/rsc/scripts/jsdoc/rhino/jsdoc.js deleted file mode 100644 index f3de7b89..00000000 --- a/rsc/scripts/jsdoc/rhino/jsdoc.js +++ /dev/null @@ -1,9 +0,0 @@ -// Platform-specific functions to support jsdoc.js - -exports.pathToUri = function(_path) { - return String( new java.io.File(_path).toURI() ); -}; - -exports.uriToPath = function(uri) { - return String( new java.io.File(new java.net.URI(uri)) ); -}; diff --git a/rsc/scripts/jsdoc/rhino/jsdoc/util/include.js b/rsc/scripts/jsdoc/rhino/jsdoc/util/include.js deleted file mode 100644 index db0ef197..00000000 --- a/rsc/scripts/jsdoc/rhino/jsdoc/util/include.js +++ /dev/null @@ -1,7 +0,0 @@ -/*global Packages: true */ -module.exports = function(filepath) { - var myGlobal = require('jsdoc/util/global'); - - var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); - Packages.org.mozilla.javascript.tools.shell.Main.processFile(cx, myGlobal, filepath); -}; diff --git a/rsc/scripts/jsdoc/rhino/os.js b/rsc/scripts/jsdoc/rhino/os.js deleted file mode 100644 index ea9553c3..00000000 --- a/rsc/scripts/jsdoc/rhino/os.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Partial Rhino implementation of Node.js' `os` module. - * @module os - * @author Jeff Williams - * @see http://nodejs.org/api/os.html - */ - -exports.EOL = String( java.lang.System.getProperty('line.separator') ); - -// clearly not accurate, but probably good enough -exports.platform = function() { - if ( String(java.lang.System.getProperty('os.name')).match(/^[Ww]in/) ) { - return 'win32'; - } - else { - return 'linux'; - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/rhino/path.js b/rsc/scripts/jsdoc/rhino/path.js deleted file mode 100644 index 73df076e..00000000 --- a/rsc/scripts/jsdoc/rhino/path.js +++ /dev/null @@ -1,399 +0,0 @@ -var isWindows = java.lang.System.getProperty("os.name").toLowerCase().contains("windows"); -var fileSeparator = exports.sep = String( java.lang.System.getProperty("file.separator") ); - -function noOp() {} - -// exported for the benefit of our `fs` shim -var asyncify = exports._asyncify = function(func) { - return function() { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var data; - - callback = typeof callback === 'function' ? callback : noOp; - - try { - data = func.apply(this, args); - process.nextTick(function() { - callback(null, data); - }); - } - catch (e) { - process.nextTick(function() { - callback(e); - }); - } - }; -}; - -/** - * Returns everything on a path except for the last item - * e.g. if the path was 'path/to/something', the return value would be 'path/to' - */ -exports.dirname = function(_path) { - var f = new java.io.File(_path); - return String(f.getParent()); -}; - -/** - * Returns the last item on a path - */ -exports.basename = function(_path, ext) { - var f = new java.io.File(_path); - var p = f.getParentFile(); - var base = String(f.getName()); - if (p != null) { - var idx = ext ? base.indexOf(ext) : -1; - if (idx !== -1) { - base = base.substring(0, base.length - ext.length); - } - } - return base; -}; - -exports.existsSync = function(_path) { - var f = new java.io.File(_path); - - if (f.isDirectory()){ - return true; - } - if (!f.exists()){ - return false; - } - if (!f.canRead()){ - return false; - } - return true; -}; - -exports.exists = asyncify(exports.existsSync); - -//Code below taken from node - -//resolves . and .. elements in a path array with directory names there -//must be no slashes, empty elements, or device names (c:\) in the array -//(so also no leading and trailing slashes - it does not distinguish -//relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for ( var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last == '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -if (isWindows) { - // Regex to split a windows path into three parts: [*, device, slash, - // tail] windows-only - var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/; - - // path.resolve([from ...], to) - // windows version - exports.resolve = function() { - var resolvedDevice = '', - resolvedTail = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1; i--) { - var path; - if (i >= 0) { - path = arguments[i]; - } else if (!resolvedDevice) { - path = process.cwd(); - } else { - // Windows has the concept of drive-specific current working - // directories. If we've resolved a drive letter but not yet an - // absolute path, get cwd for that drive. We're sure the device is not - // an unc path at this points, because unc paths are always absolute. - path = process.env['=' + resolvedDevice]; - // Verify that a drive-local cwd was found and that it actually points - // to our drive. If not, default to the drive's root. - if (!path || path.substr(0, 3).toLowerCase() !== - resolvedDevice.toLowerCase() + '\\') { - path = resolvedDevice + '\\'; - } - } - - // Skip empty and invalid entries - if (typeof path !== 'string' || !path) { - continue; - } - - var result = splitDeviceRe.exec(path), - device = result[1] || '', - isUnc = device && device.charAt(1) !== ':', - isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute - tail = result[3]; - - if (device && - resolvedDevice && - device.toLowerCase() !== resolvedDevice.toLowerCase()) { - // This path points to another device so it is not applicable - continue; - } - - if (!resolvedDevice) { - resolvedDevice = device; - } - if (!resolvedAbsolute) { - resolvedTail = tail + '\\' + resolvedTail; - resolvedAbsolute = isAbsolute; - } - - if (resolvedDevice && resolvedAbsolute) { - break; - } - } - - // Replace slashes (in UNC share name) by backslashes - resolvedDevice = resolvedDevice.replace(/\//g, '\\'); - - // At this point the path should be resolved to a full absolute path, - // but handle relative paths to be safe (might happen when process.cwd() - // fails) - - // Normalize the tail path - - function f(p) { - return !!p; - } - - resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f), - !resolvedAbsolute).join('\\'); - - return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) || - '.'; - }; - - // windows version - exports.normalize = function(_path) { - var result = splitDeviceRe.exec(_path), - device = result[1] || '', - isUnc = device && device.charAt(1) !== ':', - isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute - tail = result[3], - trailingSlash = /[\\\/]$/.test(tail); - - // Normalize the tail path - tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) { - return !!p; - }), !isAbsolute).join('\\'); - - if (!tail && !isAbsolute) { - tail = '.'; - } - if (tail && trailingSlash) { - tail += '\\'; - } - - return device + (isAbsolute ? '\\' : '') + tail; - }; - - //windows version - exports.join = function() { - function f(p) { - return p && typeof p === 'string'; - } - - var _paths = Array.prototype.slice.call(arguments, 0).filter(f); - var joined = _paths.join('\\'); - - // Make sure that the joined path doesn't start with two slashes - // - it will be mistaken for an unc path by normalize() - - // unless the _paths[0] also starts with two slashes - if (/^[\\\/]{2}/.test(joined) && !/^[\\\/]{2}/.test(_paths[0])) { - joined = joined.slice(1); - } - - return exports.normalize(joined); - }; - - // path.relative(from, to) - // it will solve the relative path from 'from' to 'to', for instance: - // from = 'C:\\orandea\\test\\aaa' - // to = 'C:\\orandea\\impl\\bbb' - // The output of the function should be: '..\\..\\impl\\bbb' - // windows version - exports.relative = function(from, to) { - from = exports.resolve(from); - to = exports.resolve(to); - - // windows is not case sensitive - var lowerFrom = from.toLowerCase(); - var lowerTo = to.toLowerCase(); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') { - break; - } - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') { - break; - } - } - - if (start > end) { - return []; - } - return arr.slice(start, end - start + 1); - } - - var toParts = trim(to.split('\\')); - - var lowerFromParts = trim(lowerFrom.split('\\')); - var lowerToParts = trim(lowerTo.split('\\')); - - var length = Math.min(lowerFromParts.length, lowerToParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (lowerFromParts[i] !== lowerToParts[i]) { - samePartsLength = i; - break; - } - } - - if (samePartsLength === 0) { - return to; - } - - var outputParts = []; - for (i = samePartsLength; i < lowerFromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('\\'); - }; -} else { - // path.resolve([from ...], to) - // posix version - exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string' || !path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; - }; - - // path.normalize(_path) - // posix version - exports.normalize = function(_path) { - var isAbsolute = _path.charAt(0) === '/', - trailingSlash = _path.slice(-1) === '/'; - - // Normalize the path - _path = normalizeArray(_path.split('/').filter(function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!_path && !isAbsolute) { - _path = '.'; - } - if (_path && trailingSlash) { - _path += '/'; - } - - return (isAbsolute ? '/' : '') + _path; - }; - - // posix version - exports.join = function() { - var _paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(_paths.filter(function(p, index) { - return p && typeof p === 'string'; - }).join('/')); - }; - - // path.relative(from, to) - // posix version - exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') { - break; - } - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') { - break; - } - } - - if (start > end) { - return []; - } - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); - }; -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/rhino/querystring.js b/rsc/scripts/jsdoc/rhino/querystring.js deleted file mode 100644 index b38921a4..00000000 --- a/rsc/scripts/jsdoc/rhino/querystring.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Adapted version of Node.js' `querystring` module. - * @module querystring - * @see http://nodejs.org/api/querystring.html - * @see https://github.com/joyent/node/blob/f105f2f2/lib/querystring.js - * @license MIT - */ -var QueryString = exports; - -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProp(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - - -QueryString.unescape = function(s) { - return decodeURIComponent(s); -}; - - -QueryString.escape = function(str) { - return encodeURIComponent(str); -}; - -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - - case 'boolean': - return v ? 'true' : 'false'; - - case 'number': - return isFinite(v) ? v : ''; - - default: - return ''; - } -}; - - -QueryString.stringify = QueryString.encode = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - - if (typeof obj === 'object') { - return Object.keys(obj).map(function(k) { - var ks = QueryString.escape(stringifyPrimitive(k)) + eq; - if (Array.isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + QueryString.escape(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + QueryString.escape(stringifyPrimitive(obj[k])); - } - }).join(sep); - - } - - if (!name) { - return ''; - } - return QueryString.escape(stringifyPrimitive(name)) + eq + - QueryString.escape(stringifyPrimitive(obj)); -}; - -// Parse a key=val string. -QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } - - var regexp = /\+/g; - qs = qs.split(sep); - - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; - } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; - } - - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; - } - - k = QueryString.unescape(kstr); - v = QueryString.unescape(vstr); - - if (!hasOwnProp(obj, k)) { - obj[k] = v; - } else if (Array.isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; - } - } - - return obj; -}; diff --git a/rsc/scripts/jsdoc/rhino/rhino-shim.js b/rsc/scripts/jsdoc/rhino/rhino-shim.js deleted file mode 100644 index 16c126f6..00000000 --- a/rsc/scripts/jsdoc/rhino/rhino-shim.js +++ /dev/null @@ -1,123 +0,0 @@ -/*global env: true, Packages: true */ -/** - * @overview A minimal emulation of the standard features of Node.js necessary - * to get JSDoc to run. - */ - -/** - * Emulate DOM timeout/interval functions. - * @see https://developer.mozilla.org/en-US/docs/DOM/window#Methods - */ - -setTimeout = null, -clearTimeout = null, -setInterval = null, -clearInterval = null; - -(function() { - // TODO: tune number of threads if necessary - var timerPool = new java.util.concurrent.ScheduledThreadPoolExecutor(10); - var timers = {}; - var timerCount = 1; - var timerUnits = java.util.concurrent.TimeUnit.MILLISECONDS; - - function getCallback(fn) { - return new java.lang.Runnable({ - run: Packages.org.mozilla.javascript.Context.call(fn) - }); - } - - setTimeout = function(fn, delay) { - var timerId = timerCount++; - var callback = getCallback(fn); - timers[timerId] = timerPool.schedule(callback, delay, timerUnits); - return timerId; - }; - - clearTimeout = function(timerId) { - if (timers[timerId]) { - timerPool.remove(timers[timerId]); - delete timers[timerId]; - } - }; - - setInterval = function(fn, delay) { - var timerId = timerCount++; - var callback = getCallback(fn); - timers[timerId] = timerPool.scheduleAtFixedRate(callback, delay, delay, timerUnits); - return timerId; - }; - - clearInterval = clearTimeout; -})(); - -/** - * Emulate Node.js console functions. - * @see http://nodejs.org/api/stdio.html - */ -console = (function() { - function println(stream, args) { - java.lang.System[stream].println( require('util').format.apply(this, args) ); - } - - return { - error: function() { - println('err', arguments); - }, - info: function() { - println('out', arguments); - }, - log: function() { - println('out', arguments); - }, - trace: function(label) { - // this puts some extra junk at the top of the stack trace, but it's close enough - var e = new java.lang.Exception(label || 'Trace'); - e.printStackTrace(); - }, - warn: function() { - println('err', arguments); - } - }; -})(); - -/** - * Emulate Node.js process functions. - * @see http://nodejs.org/api/process.html - */ -process = { - argv: [__dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0)), - cwd: function() { - return new Packages.java.io.File('.').getCanonicalPath() + ''; - }, - env: (function() { - var result = {}; - - var env = java.lang.System.getenv(); - var keys = env.keySet().toArray(); - var key; - for (var i = 0, l = keys.length; i < l; i++) { - key = keys[i]; - result[key + ''] = env.get(key) + ''; - } - - return result; - })(), - exit: function(n) { - n = n || 0; - java.lang.System.exit(n); - }, - nextTick: function(callback) { - setTimeout(callback, 0); - }, - stderr: { - write: function(str) { - java.lang.System.err.print(str); - } - }, - stdout: { - write: function(str) { - java.lang.System.out.print(str); - } - } -}; diff --git a/rsc/scripts/jsdoc/rhino/util.js b/rsc/scripts/jsdoc/rhino/util.js deleted file mode 100644 index bd696834..00000000 --- a/rsc/scripts/jsdoc/rhino/util.js +++ /dev/null @@ -1,561 +0,0 @@ -/** - * Adapted version of Node.js' `util` module. - * @module util - * @see http://nodejs.org/api/util.html - * @see https://github.com/joyent/node/blob/85090734/lib/util.js - * @license MIT - */ - -function hasOwnProp(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - - -// placate JSHint -var stylizeNoColor, stylizeWithColor, formatValue, formatPrimitive; - -/** - * Echoes the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) { - ctx.depth = arguments[2]; - } - if (arguments.length >= 4) { - ctx.colors = arguments[3]; - } - if (typeof opts === 'boolean') { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (typeof ctx.showHidden === 'undefined') { - ctx.showHidden = false; - } - if (typeof ctx.depth === 'undefined') { - ctx.depth = 2; - } - if (typeof ctx.colors === 'undefined') { - ctx.colors = false; - } - if (typeof ctx.customInspect === 'undefined') { - ctx.customInspect = true; - } - if (ctx.colors) { - ctx.stylize = stylizeWithColor; - } - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -stylizeWithColor = function(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -}; - - -stylizeNoColor = function(str, styleType) { - return str; -}; - - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - var i, len; - - if (typeof f !== 'string') { - var objects = []; - for (i = 0, len = arguments.length; i < len; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - i = 1; - var args = arguments; - len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') { - return '%'; - } - if (i >= len) { - return x; - } - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': return require('jsdoc/util/dumper').dump(args[i++]); - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (x === null || typeof x !== 'object') { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -exports.print = function() { - var args = Array.prototype.slice.call(arguments, 0); - for (var i = 0, len = args.length; i < len; ++i) { - process.stdout.write(String(args[i])); - } -}; - - -exports.puts = function() { - var args = Array.prototype.slice.call(arguments, 0); - for (var i = 0, len = args.length; i < len; ++i) { - process.stdout.write(args[i] + '\n'); - } -}; - - -exports.debug = function(x) { - process.stderr.write('DEBUG: ' + x + '\n'); -}; - - -var error = exports.error = function(x) { - var args = Array.prototype.slice.call(arguments, 0); - for (var i = 0, len = args.length; i < len; ++i) { - process.stderr.write(args[i] + '\n'); - } -}; - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProp(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (recurseTimes === null) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (typeof name === 'undefined') { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProp(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) { - numLinesEst++; - } - return prev + cur.length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar) || - (typeof ar === 'object' && objectToString(ar) === '[object Array]'); -} -exports.isArray = isArray; - - -function isRegExp(re) { - return typeof re === 'object' && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - - -function isDate(d) { - return typeof d === 'object' && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - - -function isError(e) { - return typeof e === 'object' && objectToString(e) === '[object Error]'; -} -exports.isError = isError; - - -formatValue = function(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && value && typeof value.inspect === 'function' && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - return String(value.inspect(recurseTimes)); - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (typeof value === 'function') { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (typeof value === 'function') { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length === 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -}; - - -formatPrimitive = function(ctx, value) { - switch (typeof value) { - case 'undefined': - return ctx.stylize('undefined', 'undefined'); - - case 'string': - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - - case 'number': - return ctx.stylize('' + value, 'number'); - - case 'boolean': - return ctx.stylize('' + value, 'boolean'); - } - // For some reason typeof null is "object", so special case here. - if (value === null) { - return ctx.stylize('null', 'null'); - } -}; - - -exports.p = exports.deprecate(function() { - var args = Array.prototype.slice.call(arguments, 0); - for (var i = 0, len = args.length; i < len; ++i) { - error(exports.inspect(args[i])); - } -}, 'util.p: Use console.error() instead.'); - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -exports.log = function(msg) { - exports.puts(timestamp() + ' - ' + msg.toString()); -}; - - -exports.exec = function() { - throw new Error('util.exec() is not implemented on Rhino (and was deprecated in Node.js 0.2)'); -}; - - -exports.pump = function() { - throw new Error('util.pump() is not implemented on Rhino (and was deprecated in Node.js 0.8'); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = function(ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); -}; - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || typeof add !== 'object') { - return origin; - } - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; diff --git a/rsc/scripts/jsdoc/templates/README.md b/rsc/scripts/jsdoc/templates/README.md deleted file mode 100644 index fbdd7dbf..00000000 --- a/rsc/scripts/jsdoc/templates/README.md +++ /dev/null @@ -1,20 +0,0 @@ -To create or use your own template, create a folder, and give it the name of your template, for example "mycooltemplate". Within this folder create a file named "publish.js". That file must define a global method named "publish". For example: - -````javascript -/** - * Turn the data about your docs into file output. - * @global - * @param {TAFFY} data - A TaffyDB collection representing - * all the symbols documented in your code. - * @param {object} opts - An object with options information. - */ -function publish(data, opts) { - // do stuff here to generate your output files -} -```` - -To invoke JSDoc 3 with your own template, use the `-t` command line option, giving it the path to your template folder. - -```` -./jsdoc mycode.js -t /path/to/mycooltemplate -```` \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/default/README.md b/rsc/scripts/jsdoc/templates/default/README.md deleted file mode 100644 index a7bd96bf..00000000 --- a/rsc/scripts/jsdoc/templates/default/README.md +++ /dev/null @@ -1 +0,0 @@ -The default template for JSDoc 3 uses: [the Taffy Database library](http://taffydb.com/) and the [Underscore Template library](http://documentcloud.github.com/underscore/#template). diff --git a/rsc/scripts/jsdoc/templates/default/publish.js b/rsc/scripts/jsdoc/templates/default/publish.js deleted file mode 100644 index b79200a9..00000000 --- a/rsc/scripts/jsdoc/templates/default/publish.js +++ /dev/null @@ -1,559 +0,0 @@ -/*global env: true */ -var template = require('jsdoc/template'), - fs = require('jsdoc/fs'), - path = require('jsdoc/path'), - taffy = require('taffydb').taffy, - handle = require('jsdoc/util/error').handle, - helper = require('jsdoc/util/templateHelper'), - htmlsafe = helper.htmlsafe, - linkto = helper.linkto, - resolveAuthorLinks = helper.resolveAuthorLinks, - scopeToPunc = helper.scopeToPunc, - hasOwnProp = Object.prototype.hasOwnProperty, - data, - view, - outdir = env.opts.destination; - - -function find(spec) { - return helper.find(data, spec); -} - -function tutoriallink(tutorial) { - return helper.toTutorial(tutorial, null, { tag: 'em', classname: 'disabled', prefix: 'Tutorial: ' }); -} - -function getAncestorLinks(doclet) { - return helper.getAncestorLinks(data, doclet); -} - -function hashToLink(doclet, hash) { - if ( !/^(#.+)/.test(hash) ) { return hash; } - - var url = helper.createLink(doclet); - - url = url.replace(/(#.+|$)/, hash); - return '' + hash + ''; -} - -function needsSignature(doclet) { - var needsSig = false; - - // function and class definitions always get a signature - if (doclet.kind === 'function' || doclet.kind === 'class') { - needsSig = true; - } - // typedefs that contain functions get a signature, too - else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names && - doclet.type.names.length) { - for (var i = 0, l = doclet.type.names.length; i < l; i++) { - if (doclet.type.names[i].toLowerCase() === 'function') { - needsSig = true; - break; - } - } - } - - return needsSig; -} - -function addSignatureParams(f) { - var params = helper.getSignatureParams(f, 'optional'); - - f.signature = (f.signature || '') + '('+params.join(', ')+')'; -} - -function addSignatureReturns(f) { - var returnTypes = helper.getSignatureReturns(f); - - f.signature = ''+(f.signature || '') + '' + ''+(returnTypes.length? ' → {'+returnTypes.join('|')+'}' : '')+''; -} - -function addSignatureTypes(f) { - var types = helper.getSignatureTypes(f); - - f.signature = (f.signature || '') + ''+(types.length? ' :'+types.join('|') : '')+''; -} - -function addAttribs(f) { - var attribs = helper.getAttribs(f); - - f.attribs = ''+htmlsafe(attribs.length? '<'+attribs.join(', ')+'> ' : '')+''; -} - -function shortenPaths(files, commonPrefix) { - // always use forward slashes - var regexp = new RegExp('\\\\', 'g'); - - Object.keys(files).forEach(function(file) { - files[file].shortened = files[file].resolved.replace(commonPrefix, '') - .replace(regexp, '/'); - }); - - return files; -} - -function resolveSourcePath(filepath) { - return path.resolve(process.cwd(), filepath); -} - -function getPathFromDoclet(doclet) { - if (!doclet.meta) { - return; - } - - var filepath = doclet.meta.path && doclet.meta.path !== 'null' ? - doclet.meta.path + '/' + doclet.meta.filename : - doclet.meta.filename; - - return filepath; -} - -function generate(title, docs, filename, resolveLinks) { - resolveLinks = resolveLinks === false ? false : true; - - var docData = { - title: title, - docs: docs - }; - - var outpath = path.join(outdir, filename), - html = view.render('container.tmpl', docData); - - if (resolveLinks) { - html = helper.resolveLinks(html); // turn {@link foo} into foo - } - - fs.writeFileSync(outpath, html, 'utf8'); -} - -function generateSourceFiles(sourceFiles) { - Object.keys(sourceFiles).forEach(function(file) { - var source; - // links are keyed to the shortened path in each doclet's `meta.filename` property - var sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened); - helper.registerLink(sourceFiles[file].shortened, sourceOutfile); - - try { - source = { - kind: 'source', - code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, 'utf8') ) - }; - } - catch(e) { - handle(e); - } - - generate('Source: ' + sourceFiles[file].shortened, [source], sourceOutfile, - false); - }); -} - -/** - * Look for classes or functions with the same name as modules (which indicates that the module - * exports only that class or function), then attach the classes or functions to the `module` - * property of the appropriate module doclets. The name of each class or function is also updated - * for display purposes. This function mutates the original arrays. - * - * @private - * @param {Array.} doclets - The array of classes and functions to - * check. - * @param {Array.} modules - The array of module doclets to search. - */ -function attachModuleSymbols(doclets, modules) { - var symbols = {}; - - // build a lookup table - doclets.forEach(function(symbol) { - symbols[symbol.longname] = symbol; - }); - - return modules.map(function(module) { - if (symbols[module.longname]) { - module.module = symbols[module.longname]; - module.module.name = module.module.name.replace('module:', 'require("') + '")'; - } - }); -} - -/** - * Create the navigation sidebar. - * @param {object} members The members that will be used to create the sidebar. - * @param {array} members.classes - * @param {array} members.externals - * @param {array} members.globals - * @param {array} members.mixins - * @param {array} members.modules - * @param {array} members.namespaces - * @param {array} members.tutorials - * @param {array} members.events - * @return {string} The HTML for the navigation sidebar. - */ -function buildNav(members) { - var nav = '

    Index

    ', - seen = {}, - hasClassList = false, - classNav = '', - globalNav = ''; - - if (members.modules.length) { - nav += '

    Modules

      '; - members.modules.forEach(function(m) { - if ( !hasOwnProp.call(seen, m.longname) ) { - nav += '
    • '+linkto(m.longname, m.name)+'
    • '; - } - seen[m.longname] = true; - }); - - nav += '
    '; - } - - if (members.externals.length) { - nav += '

    Externals

      '; - members.externals.forEach(function(e) { - if ( !hasOwnProp.call(seen, e.longname) ) { - nav += '
    • '+linkto( e.longname, e.name.replace(/(^"|"$)/g, '') )+'
    • '; - } - seen[e.longname] = true; - }); - - nav += '
    '; - } - - if (members.classes.length) { - members.classes.forEach(function(c) { - if ( !hasOwnProp.call(seen, c.longname) ) { - classNav += '
  • '+linkto(c.longname, c.name)+'
  • '; - } - seen[c.longname] = true; - }); - - if (classNav !== '') { - nav += '

    Classes

      '; - nav += classNav; - nav += '
    '; - } - } - - if (members.events.length) { - nav += '

    Events

      '; - members.events.forEach(function(e) { - if ( !hasOwnProp.call(seen, e.longname) ) { - nav += '
    • '+linkto(e.longname, e.name)+'
    • '; - } - seen[e.longname] = true; - }); - - nav += '
    '; - } - - if (members.namespaces.length) { - nav += '

    Namespaces

      '; - members.namespaces.forEach(function(n) { - if ( !hasOwnProp.call(seen, n.longname) ) { - nav += '
    • '+linkto(n.longname, n.name)+'
    • '; - } - seen[n.longname] = true; - }); - - nav += '
    '; - } - - if (members.mixins.length) { - nav += '

    Mixins

      '; - members.mixins.forEach(function(m) { - if ( !hasOwnProp.call(seen, m.longname) ) { - nav += '
    • '+linkto(m.longname, m.name)+'
    • '; - } - seen[m.longname] = true; - }); - - nav += '
    '; - } - - if (members.tutorials.length) { - nav += '

    Tutorials

      '; - members.tutorials.forEach(function(t) { - nav += '
    • '+tutoriallink(t.name)+'
    • '; - }); - - nav += '
    '; - } - - if (members.globals.length) { - members.globals.forEach(function(g) { - if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) { - globalNav += '
  • ' + linkto(g.longname, g.name) + '
  • '; - } - seen[g.longname] = true; - }); - - if (!globalNav) { - // turn the heading into a link so you can actually get to the global page - nav += '

    ' + linkto('global', 'Global') + '

    '; - } - else { - nav += '

    Global

      ' + globalNav + '
    '; - } - } - - return nav; -} - - -/** - @param {TAFFY} taffyData See . - @param {object} opts - @param {Tutorial} tutorials - */ -exports.publish = function(taffyData, opts, tutorials) { - data = taffyData; - - var conf = env.conf.templates || {}; - conf['default'] = conf['default'] || {}; - - var templatePath = opts.template; - view = new template.Template(templatePath + '/tmpl'); - - // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness - // doesn't try to hand them out later - var indexUrl = helper.getUniqueFilename('index'); - // don't call registerLink() on this one! 'index' is also a valid longname - - var globalUrl = helper.getUniqueFilename('global'); - helper.registerLink('global', globalUrl); - - // set up templating - view.layout = 'layout.tmpl'; - - // set up tutorials for helper - helper.setTutorials(tutorials); - - data = helper.prune(data); - data.sort('longname, version, since'); - helper.addEventListeners(data); - - var sourceFiles = {}; - var sourceFilePaths = []; - data().each(function(doclet) { - doclet.attribs = ''; - - if (doclet.examples) { - doclet.examples = doclet.examples.map(function(example) { - var caption, code; - - if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) { - caption = RegExp.$1; - code = RegExp.$3; - } - - return { - caption: caption || '', - code: code || example - }; - }); - } - if (doclet.see) { - doclet.see.forEach(function(seeItem, i) { - doclet.see[i] = hashToLink(doclet, seeItem); - }); - } - - // build a list of source files - var sourcePath; - var resolvedSourcePath; - if (doclet.meta) { - sourcePath = getPathFromDoclet(doclet); - resolvedSourcePath = resolveSourcePath(sourcePath); - sourceFiles[sourcePath] = { - resolved: resolvedSourcePath, - shortened: null - }; - sourceFilePaths.push(resolvedSourcePath); - } - }); - - // update outdir if necessary, then create outdir - var packageInfo = ( find({kind: 'package'}) || [] ) [0]; - if (packageInfo && packageInfo.name) { - outdir = path.join(outdir, packageInfo.name, packageInfo.version); - } - fs.mkPath(outdir); - - // copy the template's static files to outdir - var fromDir = path.join(templatePath, 'static'); - var staticFiles = fs.ls(fromDir, 3); - - staticFiles.forEach(function(fileName) { - var toDir = fs.toDir( fileName.replace(fromDir, outdir) ); - fs.mkPath(toDir); - fs.copyFileSync(fileName, toDir); - }); - - // copy user-specified static files to outdir - var staticFilePaths; - var staticFileFilter; - var staticFileScanner; - if (conf['default'].staticFiles) { - staticFilePaths = conf['default'].staticFiles.paths || []; - staticFileFilter = new (require('jsdoc/src/filter')).Filter(conf['default'].staticFiles); - staticFileScanner = new (require('jsdoc/src/scanner')).Scanner(); - - staticFilePaths.forEach(function(filePath) { - var extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter); - - extraStaticFiles.forEach(function(fileName) { - var sourcePath = fs.statSync(filePath).isDirectory() ? filePath : - path.dirname(filePath); - var toDir = fs.toDir( fileName.replace(sourcePath, outdir) ); - fs.mkPath(toDir); - fs.copyFileSync(fileName, toDir); - }); - }); - } - - if (sourceFilePaths.length) { - sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) ); - } - data().each(function(doclet) { - var url = helper.createLink(doclet); - helper.registerLink(doclet.longname, url); - - // replace the filename with a shortened version of the full path - var docletPath; - if (doclet.meta) { - docletPath = getPathFromDoclet(doclet); - docletPath = sourceFiles[docletPath].shortened; - if (docletPath) { - doclet.meta.filename = docletPath; - } - } - }); - - data().each(function(doclet) { - var url = helper.longnameToUrl[doclet.longname]; - - if (url.indexOf('#') > -1) { - doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop(); - } - else { - doclet.id = doclet.name; - } - - if ( needsSignature(doclet) ) { - addSignatureParams(doclet); - addSignatureReturns(doclet); - addAttribs(doclet); - } - }); - - // do this after the urls have all been generated - data().each(function(doclet) { - doclet.ancestors = getAncestorLinks(doclet); - - if (doclet.kind === 'member') { - addSignatureTypes(doclet); - addAttribs(doclet); - } - - if (doclet.kind === 'constant') { - addSignatureTypes(doclet); - addAttribs(doclet); - doclet.kind = 'member'; - } - }); - - var members = helper.getMembers(data); - members.tutorials = tutorials.children; - - // add template helpers - view.find = find; - view.linkto = linkto; - view.resolveAuthorLinks = resolveAuthorLinks; - view.tutoriallink = tutoriallink; - view.htmlsafe = htmlsafe; - - // once for all - view.nav = buildNav(members); - attachModuleSymbols( find({ kind: ['class', 'function'], longname: {left: 'module:'} }), - members.modules ); - - // only output pretty-printed source files if requested; do this before generating any other - // pages, so the other pages can link to the source files - if (conf['default'].outputSourceFiles) { - generateSourceFiles(sourceFiles); - } - - if (members.globals.length) { generate('Global', [{kind: 'globalobj'}], globalUrl); } - - // index page displays information from package.json and lists files - var files = find({kind: 'file'}), - packages = find({kind: 'package'}); - - generate('Index', - packages.concat( - [{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}] - ).concat(files), - indexUrl); - - // set up the lists that we'll use to generate pages - var classes = taffy(members.classes); - var modules = taffy(members.modules); - var namespaces = taffy(members.namespaces); - var mixins = taffy(members.mixins); - var externals = taffy(members.externals); - - Object.keys(helper.longnameToUrl).forEach(function(longname) { - var myClasses = helper.find(classes, {longname: longname}); - if (myClasses.length) { - generate('Class: ' + myClasses[0].name, myClasses, helper.longnameToUrl[longname]); - } - - var myModules = helper.find(modules, {longname: longname}); - if (myModules.length) { - generate('Module: ' + myModules[0].name, myModules, helper.longnameToUrl[longname]); - } - - var myNamespaces = helper.find(namespaces, {longname: longname}); - if (myNamespaces.length) { - generate('Namespace: ' + myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]); - } - - var myMixins = helper.find(mixins, {longname: longname}); - if (myMixins.length) { - generate('Mixin: ' + myMixins[0].name, myMixins, helper.longnameToUrl[longname]); - } - - var myExternals = helper.find(externals, {longname: longname}); - if (myExternals.length) { - generate('External: ' + myExternals[0].name, myExternals, helper.longnameToUrl[longname]); - } - }); - - // TODO: move the tutorial functions to templateHelper.js - function generateTutorial(title, tutorial, filename) { - var tutorialData = { - title: title, - header: tutorial.title, - content: tutorial.parse(), - children: tutorial.children - }; - - var tutorialPath = path.join(outdir, filename), - html = view.render('tutorial.tmpl', tutorialData); - - // yes, you can use {@link} in tutorials too! - html = helper.resolveLinks(html); // turn {@link foo} into foo - - fs.writeFileSync(tutorialPath, html, 'utf8'); - } - - // tutorials can have only one parent so there is no risk for loops - function saveChildren(node) { - node.children.forEach(function(child) { - generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name)); - saveChildren(child); - }); - } - saveChildren(tutorials); -}; diff --git a/rsc/scripts/jsdoc/templates/default/static/scripts/linenumber.js b/rsc/scripts/jsdoc/templates/default/static/scripts/linenumber.js deleted file mode 100644 index a0c570d5..00000000 --- a/rsc/scripts/jsdoc/templates/default/static/scripts/linenumber.js +++ /dev/null @@ -1,17 +0,0 @@ -(function() { - var counter = 0; - var numbered; - var source = document.getElementsByClassName('prettyprint source'); - - if (source && source[0]) { - source = source[0].getElementsByTagName('code')[0]; - - numbered = source.innerHTML.split('\n'); - numbered = numbered.map(function(item) { - counter++; - return '' + item; - }); - - source.innerHTML = numbered.join('\n'); - } -})(); diff --git a/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/Apache-License-2.0.txt b/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/Apache-License-2.0.txt deleted file mode 100644 index d6456956..00000000 --- a/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/Apache-License-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/lang-css.js b/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/lang-css.js deleted file mode 100644 index 041e1f59..00000000 --- a/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/lang-css.js +++ /dev/null @@ -1,2 +0,0 @@ -PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", -/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/prettify.js b/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/prettify.js deleted file mode 100644 index eef5ad7e..00000000 --- a/rsc/scripts/jsdoc/templates/default/static/scripts/prettify/prettify.js +++ /dev/null @@ -1,28 +0,0 @@ -var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; -(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= -[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), -l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, -q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, -q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, -"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), -a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} -for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], -"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], -H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], -J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ -I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), -["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", -/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), -["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", -hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= -!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p - - - - - - - -
    - -
    -

    - - - - - -

    - -
    - -
    - -
    -
    - - - - - - - - -
    - - - - - -

    Example 1? 's':'' ?>

    - - - -
    - - -

    Extends

    - -
      -
    • -
    - - - -

    Mixes In

    - -
      -
    • -
    - - - -

    Requires

    - -
      -
    • -
    - - - -

    Classes

    - -
    -
    -
    -
    - - - -

    Namespaces

    - -
    -
    -
    -
    - - - -

    Members

    - -
    - -
    - - - -

    Methods

    - -
    - -
    - - - -

    Type Definitions

    - -
    - - - -
    - - - -

    Events

    - -
    - -
    - -
    - -
    - - - diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/details.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/details.tmpl deleted file mode 100644 index d3b35522..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/details.tmpl +++ /dev/null @@ -1,98 +0,0 @@ - -
    - - -
    Properties:
    - -
    - - - - -
    Version:
    -
    - - - -
    Since:
    -
    - - - -
    Inherited From:
    -
    • - -
    - - - -
    Deprecated:
    • Yes
      - - - -
      Author:
      -
      -
        -
      • -
      -
      - - - - - - - - -
      License:
      -
      - - - -
      Default Value:
      -
      - - - -
      Source:
      -
      • - , -
      - - - -
      Tutorials:
      -
      -
        -
      • -
      -
      - - - -
      See:
      -
      -
        -
      • -
      -
      - - - -
      To Do:
      -
      -
        -
      • -
      -
      - -
      diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/example.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/example.tmpl deleted file mode 100644 index e87caa5b..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/example.tmpl +++ /dev/null @@ -1,2 +0,0 @@ - -
      diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/examples.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/examples.tmpl deleted file mode 100644 index 23384c9d..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/examples.tmpl +++ /dev/null @@ -1,11 +0,0 @@ - -

      - -
      - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/exceptions.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/exceptions.tmpl deleted file mode 100644 index 78c4e250..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/exceptions.tmpl +++ /dev/null @@ -1,30 +0,0 @@ - - -
      -
      -
      - -
      -
      -
      -
      -
      - Type -
      -
      - -
      -
      -
      -
      - -
      - - - - - -
      - diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/layout.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/layout.tmpl deleted file mode 100644 index 827b5acb..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/layout.tmpl +++ /dev/null @@ -1,38 +0,0 @@ - - - - - JSDoc: <?js= title ?> - - - - - - - - - - -
      - -

      - - -
      - - - -
      - -
      - Documentation generated by JSDoc on -
      - - - - - diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/mainpage.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/mainpage.tmpl deleted file mode 100644 index 64e9e594..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/mainpage.tmpl +++ /dev/null @@ -1,14 +0,0 @@ - - - -

      - - - -
      -
      -
      - diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/members.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/members.tmpl deleted file mode 100644 index 3fded716..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/members.tmpl +++ /dev/null @@ -1,34 +0,0 @@ - -
      -

      - - -

      - -
      -
      - -
      - -
      - - - -
      Type:
      -
        -
      • - -
      • -
      - - - - - -
      Example 1? 's':'' ?>
      - - -
      diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/method.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/method.tmpl deleted file mode 100644 index 1fff9b86..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/method.tmpl +++ /dev/null @@ -1,90 +0,0 @@ - -
      -

      - - -

      - -
      -
      - - -
      - -
      - - - -
      Type:
      -
        -
      • - -
      • -
      - - - -
      This:
      -
      - - - -
      Parameters:
      - - - - - - -
      Fires:
      -
        -
      • -
      - - - -
      Listens to Events:
      -
        -
      • -
      - - - -
      Listeners of This Event:
      -
        -
      • -
      - - - -
      Throws:
      - 1) { ?>
        -
      • -
      - - - - -
      Returns:
      - 1) { ?>
        -
      • -
      - - - - -
      Example 1? 's':'' ?>
      - - -
      diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/params.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/params.tmpl deleted file mode 100644 index 7b951149..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/params.tmpl +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeArgumentDefaultDescription
      - - - - - - <optional>
      - - - - <nullable>
      - - - - <repeatable>
      - -
      - - - - -
      Properties
      - -
      \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/properties.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/properties.tmpl deleted file mode 100644 index 97a3d23a..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/properties.tmpl +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeArgumentDefaultDescription
      - - - - - - <optional>
      - - - - <nullable>
      - -
      - - - - -
      Properties
      -
      \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/returns.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/returns.tmpl deleted file mode 100644 index 32e059ed..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/returns.tmpl +++ /dev/null @@ -1,19 +0,0 @@ - -
      - -
      - - - -
      -
      - Type -
      -
      - -
      -
      - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/source.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/source.tmpl deleted file mode 100644 index e1092ef2..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/source.tmpl +++ /dev/null @@ -1,8 +0,0 @@ - -
      -
      -
      -
      -
      \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/tutorial.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/tutorial.tmpl deleted file mode 100644 index b0c79c1d..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/tutorial.tmpl +++ /dev/null @@ -1,19 +0,0 @@ -
      - -
      - 0) { ?> -
        -
      • -
      - - -

      -
      - -
      - -
      - -
      diff --git a/rsc/scripts/jsdoc/templates/default/tmpl/type.tmpl b/rsc/scripts/jsdoc/templates/default/tmpl/type.tmpl deleted file mode 100644 index db8194d6..00000000 --- a/rsc/scripts/jsdoc/templates/default/tmpl/type.tmpl +++ /dev/null @@ -1,7 +0,0 @@ - - -| - \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/haruki/README.md b/rsc/scripts/jsdoc/templates/haruki/README.md deleted file mode 100644 index ee6d36f1..00000000 --- a/rsc/scripts/jsdoc/templates/haruki/README.md +++ /dev/null @@ -1,39 +0,0 @@ -OVERVIEW -======== - -JSDoc 3 Haruki is an experimental template optimised for use with publishing processes that consume either JSON or XML. Whereas the default JSDoc template outputs an HTML representation of your API, Haruki will output a JSON, or optionally an XML, representation. - -Currently Haruki only supports a subset of the tags supported by the default template. Those are: - - * @name - * @desc - * @type - * @namespace - * @method (or @function) - * @member (or @var) - * @class - * @mixin - * @event - * @param - * @returns - * @throws - * @example - * @access (like @private or @public) - -This limited support set is intentional, as it is meant to be a usable set that could be shared with either JavaScript or PHP documentation -- another experimental tool, named "Vonnegut", can produce Haruki compatible JSON from PHPDoc tags. - -Note: `@link`s will appear in the output untransformed, there is no way to know at this stage what the file layout of your output will eventually be. It is assumed that whatever process emits the final output file/s will transform `@link` tags at that point. - -USAGE -===== - - ./jsdoc myscript.js -t templates/haruki -d console -q format=xml - -The results of this command will appear in `stdout` and can be piped into other tools for further processing. - -MORE -===== - -If you are interested in Haruki, you are encouraged to discuss your questions or ideas on the JSDoc-Users mailing list and fork/contribute to this project. - -For more information contact Michael Mathews at . \ No newline at end of file diff --git a/rsc/scripts/jsdoc/templates/haruki/publish.js b/rsc/scripts/jsdoc/templates/haruki/publish.js deleted file mode 100644 index 45c79876..00000000 --- a/rsc/scripts/jsdoc/templates/haruki/publish.js +++ /dev/null @@ -1,220 +0,0 @@ -/** - @overview Builds a tree-like JSON string from the doclet data. - @version 0.0.3 - @example - ./jsdoc scratch/jsdoc_test.js -t templates/haruki -d console -q format=xml - */ - -function graft(parentNode, childNodes, parentLongname, parentName) { - childNodes - .filter(function (element) { - return (element.memberof === parentLongname); - }) - .forEach(function (element, index) { - var i, - len; - - if (element.kind === 'namespace') { - if (! parentNode.namespaces) { - parentNode.namespaces = []; - } - - var thisNamespace = { - 'name': element.name, - 'description': element.description || '', - 'access': element.access || '', - 'virtual': !!element.virtual - }; - - parentNode.namespaces.push(thisNamespace); - - graft(thisNamespace, childNodes, element.longname, element.name); - } - else if (element.kind === 'mixin') { - if (! parentNode.mixins) { - parentNode.mixins = []; - } - - var thisMixin = { - 'name': element.name, - 'description': element.description || '', - 'access': element.access || '', - 'virtual': !!element.virtual - }; - - parentNode.mixins.push(thisMixin); - - graft(thisMixin, childNodes, element.longname, element.name); - } - else if (element.kind === 'function') { - if (! parentNode.functions) { - parentNode.functions = []; - } - - var thisFunction = { - 'name': element.name, - 'access': element.access || '', - 'virtual': !!element.virtual, - 'description': element.description || '', - 'parameters': [ ], - 'examples': [] - }; - - parentNode.functions.push(thisFunction); - - if (element.returns) { - thisFunction.returns = { - 'type': element.returns[0].type? (element.returns[0].type.names.length === 1? element.returns[0].type.names[0] : element.returns[0].type.names) : '', - 'description': element.returns[0].description || '' - }; - } - - if (element.examples) { - for (i = 0, len = element.examples.length; i < len; i++) { - thisFunction.examples.push(element.examples[i]); - } - } - - if (element.params) { - for (i = 0, len = element.params.length; i < len; i++) { - thisFunction.parameters.push({ - 'name': element.params[i].name, - 'type': element.params[i].type? (element.params[i].type.names.length === 1? element.params[i].type.names[0] : element.params[i].type.names) : '', - 'description': element.params[i].description || '', - 'default': element.params[i].defaultvalue || '', - 'optional': typeof element.params[i].optional === 'boolean'? element.params[i].optional : '', - 'nullable': typeof element.params[i].nullable === 'boolean'? element.params[i].nullable : '' - }); - } - } - } - else if (element.kind === 'member') { - if (! parentNode.properties) { - parentNode.properties = []; - } - parentNode.properties.push({ - 'name': element.name, - 'access': element.access || '', - 'virtual': !!element.virtual, - 'description': element.description || '', - 'type': element.type? (element.type.length === 1? element.type[0] : element.type) : '' - }); - } - - else if (element.kind === 'event') { - if (! parentNode.events) { - parentNode.events = []; - } - - var thisEvent = { - 'name': element.name, - 'access': element.access || '', - 'virtual': !!element.virtual, - 'description': element.description || '', - 'parameters': [], - 'examples': [] - }; - - parentNode.events.push(thisEvent); - - if (element.returns) { - thisEvent.returns = { - 'type': element.returns.type? (element.returns.type.names.length === 1? element.returns.type.names[0] : element.returns.type.names) : '', - 'description': element.returns.description || '' - }; - } - - if (element.examples) { - for (i = 0, len = element.examples.length; i < len; i++) { - thisEvent.examples.push(element.examples[i]); - } - } - - if (element.params) { - for (i = 0, len = element.params.length; i < len; i++) { - thisEvent.parameters.push({ - 'name': element.params[i].name, - 'type': element.params[i].type? (element.params[i].type.names.length === 1? element.params[i].type.names[0] : element.params[i].type.names) : '', - 'description': element.params[i].description || '', - 'default': element.params[i].defaultvalue || '', - 'optional': typeof element.params[i].optional === 'boolean'? element.params[i].optional : '', - 'nullable': typeof element.params[i].nullable === 'boolean'? element.params[i].nullable : '' - }); - } - } - } - else if (element.kind === 'class') { - if (! parentNode.classes) { - parentNode.classes = []; - } - - var thisClass = { - 'name': element.name, - 'description': element.classdesc || '', - 'extends': element.augments || [], - 'access': element.access || '', - 'virtual': !!element.virtual, - 'fires': element.fires || '', - 'constructor': { - 'name': element.name, - 'description': element.description || '', - 'parameters': [ - ], - 'examples': [] - } - }; - - parentNode.classes.push(thisClass); - - if (element.examples) { - for (i = 0, len = element.examples.length; i < len; i++) { - thisClass.constructor.examples.push(element.examples[i]); - } - } - - if (element.params) { - for (i = 0, len = element.params.length; i < len; i++) { - thisClass.constructor.parameters.push({ - 'name': element.params[i].name, - 'type': element.params[i].type? (element.params[i].type.names.length === 1? element.params[i].type.names[0] : element.params[i].type.names) : '', - 'description': element.params[i].description || '', - 'default': element.params[i].defaultvalue || '', - 'optional': typeof element.params[i].optional === 'boolean'? element.params[i].optional : '', - 'nullable': typeof element.params[i].nullable === 'boolean'? element.params[i].nullable : '' - }); - } - } - - graft(thisClass, childNodes, element.longname, element.name); - } - }); -} - -/** - @param {TAFFY} data - @param {object} opts - */ -exports.publish = function(data, opts) { - - var root = {}, - docs; - - data({undocumented: true}).remove(); - docs = data().get(); // <-- an array of Doclet objects - - graft(root, docs); - - if (opts.destination === 'console') { - if (opts.query && opts.query.format === 'xml') { - var xml = require('js2xmlparser'); - console.log( xml('jsdoc', root) ); - } - else { - dump(root); - } - } - else { - console.log('This template only supports output to the console. Use the option "-d console" when you run JSDoc.'); - } - -}; diff --git a/rsc/scripts/jsdoc/test/README.md b/rsc/scripts/jsdoc/test/README.md deleted file mode 100644 index dc8f9d96..00000000 --- a/rsc/scripts/jsdoc/test/README.md +++ /dev/null @@ -1,45 +0,0 @@ -Testing JSDoc 3 -=============== - -Running Tests -------------- - -Running tests is easy. Just change your working directory to the jsdoc folder -and run the following command on Windows: - - jsdoc -T - -Or on OS X, Linux, and other POSIX-compliant platforms: - - ./jsdoc -T - -If you can't get the short-form commands to work, try invoking Java directly: - - java -cp lib/js.jar org.mozilla.javascript.tools.shell.Main \ - -modules node_modules -modules rhino -modules lib -modules . \ - jsdoc.js -T - -Writing Tests -------------- - -Adding tests is pretty easy, too. You can write tests for JSDoc itself (to -make sure tags and the parser, etc. are working properly), tests for plugins, and/or -tests for templates. - -JSDoc 3 uses Jasmine (https://github.com/pivotal/jasmine) as its testing framework. -Take a look at that project's wiki for documentation on writing tests in general. - -### Tests for JSDoc - -Take a look at the files in the ```test``` directory for many examples of -writing tests for JSDoc itself. The ```test\fixtures``` directory hold fixtures -for use in the tests, and the ```test\specs``` directory holds the tests themselves. - -### Tests for plugins - -Tests for plugins are found in the ```plugins\test``` directory. Plugins containing -tests that were installed with the Jakefile install task will be run automatically. - -### Tests for templates - -TODO \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/async-callback.js b/rsc/scripts/jsdoc/test/async-callback.js deleted file mode 100644 index d2388fa4..00000000 --- a/rsc/scripts/jsdoc/test/async-callback.js +++ /dev/null @@ -1,57 +0,0 @@ -/*global jasmine: true */ -(function() { - var withoutAsync = {}; - - ["it", "beforeEach", "afterEach"].forEach(function(jasmineFunction) { - withoutAsync[jasmineFunction] = jasmine.Env.prototype[jasmineFunction]; - return jasmine.Env.prototype[jasmineFunction] = function() { - var args = Array.prototype.slice.call(arguments, 0); - var timeout = null; - if (isLastArgumentATimeout(args)) { - timeout = args.pop(); - } - if (isLastArgumentAnAsyncSpecFunction(args)) - { - var specFunction = args.pop(); - args.push(function() { - return asyncSpec(specFunction, this, timeout); - }); - } - return withoutAsync[jasmineFunction].apply(this, args); - }; - }); - - function isLastArgumentATimeout(args) - { - return args.length > 0 && (typeof args[args.length-1]) === "number"; - } - - function isLastArgumentAnAsyncSpecFunction(args) - { - return args.length > 0 && (typeof args[args.length-1]) === "function" && args[args.length-1].length > 0; - } - - function asyncSpec(specFunction, spec, timeout) { - if (timeout == null){timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL || 1000;} - var done = false; - spec.runs(function() { - try { - return specFunction(function(error) { - done = true; - if (error != null) { - return spec.fail(error); - } - }); - } catch (e) { - done = true; - throw e; - } - }); - return spec.waitsFor(function() { - if (done === true) { - return true; - } - }, "spec to complete", timeout); - } - -}).call(this); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/abstracttag.js b/rsc/scripts/jsdoc/test/fixtures/abstracttag.js deleted file mode 100644 index 07aeb9b7..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/abstracttag.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @constructor */ -function Thingy() { - - /** @abstract */ - this.pez = 2; - -} - -// same as... - -/** @constructor */ -function OtherThingy() { - - /** @virtual */ - this.pez = 2; - -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/accesstag.js b/rsc/scripts/jsdoc/test/fixtures/accesstag.js deleted file mode 100644 index 497c20dd..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/accesstag.js +++ /dev/null @@ -1,29 +0,0 @@ -/** @constructor */ -function Thingy() { - - /** @access private */ - var foo = 0; - - /** @access protected */ - this._bar = 1; - - /** @access public */ - this.pez = 2; - -} - -// same as... - -/** @constructor */ -function OtherThingy() { - - /** @private */ - var foo = 0; - - /** @protected */ - this._bar = 1; - - /** @public */ - this.pez = 2; - -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/alias.js b/rsc/scripts/jsdoc/test/fixtures/alias.js deleted file mode 100644 index bbb7305c..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/alias.js +++ /dev/null @@ -1,13 +0,0 @@ -var myObject = (function() { - - /** Give x another name. - @alias myObject - @namespace - */ - var x = { - /** document me */ - myProperty: 'foo' - } - - return x; -})(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/alias2.js b/rsc/scripts/jsdoc/test/fixtures/alias2.js deleted file mode 100644 index e1d8e5a5..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/alias2.js +++ /dev/null @@ -1,10 +0,0 @@ -(function() { - - /** @alias ns.Myclass# */ - var x = { - /** document me */ - myProperty: 'foo' - } - - return x; -})(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/alias3.js b/rsc/scripts/jsdoc/test/fixtures/alias3.js deleted file mode 100644 index 3cea9aba..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/alias3.js +++ /dev/null @@ -1,12 +0,0 @@ -Klass('trackr.CookieManager', - - /** @class - @alias trackr.CookieManager - @param {object} kv - */ - function(kv) { - /** document me */ - this.value = kv; - } - -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/aliasglobal.js b/rsc/scripts/jsdoc/test/fixtures/aliasglobal.js deleted file mode 100644 index 376a43a1..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/aliasglobal.js +++ /dev/null @@ -1,7 +0,0 @@ -(function() { - - /** @alias .log */ - var log = function() { - } - -})(); diff --git a/rsc/scripts/jsdoc/test/fixtures/aliasglobal2.js b/rsc/scripts/jsdoc/test/fixtures/aliasglobal2.js deleted file mode 100644 index 61f8082d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/aliasglobal2.js +++ /dev/null @@ -1,18 +0,0 @@ -(function () { - /** - * Creates a new test object. - * @alias Test - * @constructor - */ - var Test = function(testName) { - /** Document me. */ - this.name = testName; - } - - /** Document me. */ - Test.prototype.run = function(message) { - }; - - /** Document me. */ - Test.counter = 1; -})(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/aliasresolve.js b/rsc/scripts/jsdoc/test/fixtures/aliasresolve.js deleted file mode 100644 index 8e9ec186..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/aliasresolve.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @namespace - */ -var A = {}; - -(function(ns) { - /** - * @namespace - * @alias A.F - */ - var f = {}; - - /** - * @return {String} - */ - f.method = function(){}; - - ns.F = f; -})(A); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/aliasresolve2.js b/rsc/scripts/jsdoc/test/fixtures/aliasresolve2.js deleted file mode 100644 index 4ff8b282..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/aliasresolve2.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @namespace - */ -var A = {}; - -/** - * @namespace - * @alias A.F - */ -var f = {}; - -(function(ns) { - /** - * @return {String} - */ - f.method = function(){}; - - ns.F = f; -})(A); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/also.js b/rsc/scripts/jsdoc/test/fixtures/also.js deleted file mode 100644 index 96a109ef..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/also.js +++ /dev/null @@ -1,46 +0,0 @@ -/** @class */ -function Asset() { - this._name = ''; - this._shape = ''; - this._shhhhKeepThisSecret = ''; -} - -/** - * - * Set the value of the name property. - * @param {string} newName - * - *//** - * - * Get the value of the name property. - * @returns {string} - * - */ -Asset.prototype.name = function(newName) { - if (newName) { this._name = newName; } - else { return this._name; } -}; - -/** - * Set the value of the shape property. - * @param {string} newShape - *//** - * Set the value of the shape property, plus some other property. - * @param {string} newShape - * @param {string} mysteryProperty - *//** - * Get the value of the shape property. - * @returns {string} - */ -Asset.prototype.shape = function(newShape, mysteryProperty) { - if (newShape && mysteryProperty) { - this._shape = newShape; - this._shhhhKeepThisSecret = mysteryProperty; - } - else if (newShape) { - this._shape = newShape; - } - else { - return this._shape; - } -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/augmentstag.js b/rsc/scripts/jsdoc/test/fixtures/augmentstag.js deleted file mode 100644 index a30a1e22..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/augmentstag.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @constructor - */ -function Foo() { - /** First property */ - this.prop1 = true; -} - -/** - * Second property - * @type {String} - */ -Foo.prototype.prop2 = "parent prop2"; - -/** - * First parent method. - */ -Foo.prototype.method1 = function() {}; - -/** - * Second parent method. - */ -Foo.prototype.method2 = function() {}; - - -/** - * @constructor - * @extends Foo - */ -function Bar() { - /** Thrid prop **/ - this.prop3 = true; -} - -/** - * Second child method. - */ -Bar.prototype.method2 = function() {}; - -/** - * @constructor - * @extends {Bar} - */ -function Baz() { - /** Override prop1 */ - this.prop1 = "new"; -} - -/** - * Third grandchild method. - */ -Baz.prototype.method3 = function() {}; - diff --git a/rsc/scripts/jsdoc/test/fixtures/augmentstag2.js b/rsc/scripts/jsdoc/test/fixtures/augmentstag2.js deleted file mode 100644 index 8def33a9..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/augmentstag2.js +++ /dev/null @@ -1,6 +0,0 @@ -// Test for @augments/@extends tags that refer to undefined symbols -/** - * @constructor - * @extends UndocumentedThing - */ -function Qux() {} diff --git a/rsc/scripts/jsdoc/test/fixtures/augmentstag3.js b/rsc/scripts/jsdoc/test/fixtures/augmentstag3.js deleted file mode 100644 index 80851817..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/augmentstag3.js +++ /dev/null @@ -1,18 +0,0 @@ -// test to see that we can @augment multiple things (code allows for it) -/** @class */ -function Foo() { -} -/** A method. */ -Foo.prototype.method1 = function () {}; - -/** @class */ -function Bar() { -} -/** Another method. */ -Bar.prototype.method2 = function () {} - -/** @class - * @augments Foo - * @augments Bar */ -function FooBar() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/authortag.js b/rsc/scripts/jsdoc/test/fixtures/authortag.js deleted file mode 100644 index 3bba0f0f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/authortag.js +++ /dev/null @@ -1,10 +0,0 @@ -/** @constructor - @author Michael Mathews -*/ -function Thingy() { -} - -/** @author John Doe - * @author Jane Doe */ -function Thingy2() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/borrowstag.js b/rsc/scripts/jsdoc/test/fixtures/borrowstag.js deleted file mode 100644 index b6d065dd..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/borrowstag.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @namespace - @borrows trstr as trim -*/ -var util = { - "trim": trstr -}; - -/** - Remove whitespace from around a string. - @param {string} str - */ -function trstr(str) { -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/borrowstag2.js b/rsc/scripts/jsdoc/test/fixtures/borrowstag2.js deleted file mode 100644 index 9e80dd0d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/borrowstag2.js +++ /dev/null @@ -1,21 +0,0 @@ -/** @namespace - @borrows rtrim -*/ -var str = { - rtrim: util.rtrim -}; - -/** @namespace - @borrows rtrim -*/ -var util = { - rtrim: rtrim -}; - -/** - Remove whitespace from the right side of a string. - @param {string} str - */ -function rtrim(str) { -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/callbacktag.js b/rsc/scripts/jsdoc/test/fixtures/callbacktag.js deleted file mode 100644 index 5dd468d5..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/callbacktag.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @param {requestResponseCallback} cb - */ -function makeSpecialRequest(cb) { -} - -/** - * @param {wrongTypeCallback} cb - */ -function makeExtraSpecialRequest(cb) { -} - -/** - * @callback requestResponseCallback - * @param {number} responseCode - * @param {string} responseText - */ - -/** - * @callback {(object|string)} wrongTypeCallback - */ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/classdesctag.js b/rsc/scripts/jsdoc/test/fixtures/classdesctag.js deleted file mode 100644 index 707a79e6..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/classdesctag.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Asdf. - * @class - * @classdesc A description of the class. - */ -function Foo () { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/classtag.js b/rsc/scripts/jsdoc/test/fixtures/classtag.js deleted file mode 100644 index ea4584b1..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/classtag.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - Describe the Ticker class here. - @class - */ -var Ticker = function() { - -}; - -/** - Describe the NewsSource class here. - @class NewsSource - */ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/constanttag.js b/rsc/scripts/jsdoc/test/fixtures/constanttag.js deleted file mode 100644 index a9f78058..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constanttag.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @constant */ -var FOO = 1; - -/** @const BAR */ - -/** @const {string} BAZ */ diff --git a/rsc/scripts/jsdoc/test/fixtures/constructortag.js b/rsc/scripts/jsdoc/test/fixtures/constructortag.js deleted file mode 100644 index 275ef3c6..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constructortag.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - Describe your constructor function here. - @class Describe your class here. - @constructor - @param {string} url - @throws MalformedURL - */ -function Feed(url) { -} - -/** - Document your method here. -*/ -Feed.prototype.refresh = function() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/constructstag.js b/rsc/scripts/jsdoc/test/fixtures/constructstag.js deleted file mode 100644 index a31a1cd0..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constructstag.js +++ /dev/null @@ -1,19 +0,0 @@ -Classify('TextBlock', { - - /** - Document your constructor function here. - @constructs TextBlock - @classdesc Describe your class here - @param {object} opts - @throws MissingNode - */ - construct: function(node, opts) { - }, - - /** - Document your method here. - @memberof TextBlock# - */ - align: function() { - } -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/constructstag2.js b/rsc/scripts/jsdoc/test/fixtures/constructstag2.js deleted file mode 100644 index 604d4bad..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constructstag2.js +++ /dev/null @@ -1,16 +0,0 @@ -Classify('Menu', - /** - @constructs Menu - @param items - */ - function (items) { - - }, - { - /** - @memberof Menu# - */ - show: function(){ - } - } -); diff --git a/rsc/scripts/jsdoc/test/fixtures/constructstag3.js b/rsc/scripts/jsdoc/test/fixtures/constructstag3.js deleted file mode 100644 index 3b4e410f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constructstag3.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - A class that represents a person. - @class - */ -var Person = Class.create({ - - /** - @constructs Person - @param {string} name - */ - initialize: function(name) { - - /** The name of the person. */ - this.name = name; - }, - - /** - @memberof Person# - @param {string} message - */ - say: function(message) { - - /** The person's message. */ - this.message = message; - } -}); diff --git a/rsc/scripts/jsdoc/test/fixtures/constructstag4.js b/rsc/scripts/jsdoc/test/fixtures/constructstag4.js deleted file mode 100644 index f00cbf35..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constructstag4.js +++ /dev/null @@ -1,24 +0,0 @@ -var Person = Class.create(/** @lends Person# */{ - - /** - Describe the constructor. - @classdesc A class that represents a person. - @constructs - @param {string} name - */ - initialize: function(name) { - - /** The name of the person. */ - this.name = name; - }, - - /** - @param {string} message - */ - say: function(message) { - - /** The person's message. */ - this.message = message; - } -}); - diff --git a/rsc/scripts/jsdoc/test/fixtures/constructstag5.js b/rsc/scripts/jsdoc/test/fixtures/constructstag5.js deleted file mode 100644 index 93063a5a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/constructstag5.js +++ /dev/null @@ -1,14 +0,0 @@ -Duck = (function() { - return /** @lends Duck# */ { - /** - Constructs a duck. - @constructs - @param tog - */ - constructor: function(tog) { - }, - /** Say hello. */ - quack: function() { - } - } -})(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/copyrighttag.js b/rsc/scripts/jsdoc/test/fixtures/copyrighttag.js deleted file mode 100644 index 68a09f34..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/copyrighttag.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @constructor - @copyright (c) 2011 Michael Mathews -*/ -function Thingy() { - -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/defaulttag.js b/rsc/scripts/jsdoc/test/fixtures/defaulttag.js deleted file mode 100644 index bd8461aa..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/defaulttag.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - @default - */ -var request = null; - -/** - @default - */ -var response = 'ok'; - -/** - @default - */ -var rcode = 200; - -/** - @default - */ -var rvalid = true; - -/** - @default - */ -var rerrored = false; - -/** - @default the parent window - */ -var win = getParentWindow(); - -/** - @default - */ -var header = getHeaders(request); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/deprecatedtag.js b/rsc/scripts/jsdoc/test/fixtures/deprecatedtag.js deleted file mode 100644 index 6b6269cb..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/deprecatedtag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @deprecated -*/ -function foo() { - -} - -/** @deprecated since version 2.0 -*/ -function bar() { - -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/descriptiontag.js b/rsc/scripts/jsdoc/test/fixtures/descriptiontag.js deleted file mode 100644 index 78d9d05a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/descriptiontag.js +++ /dev/null @@ -1,7 +0,0 @@ -/** Blah Blah Blah - * @desc halb halb halb - */ -var x; - -/** @description lkjasdf */ -var y; diff --git a/rsc/scripts/jsdoc/test/fixtures/destructuring.js b/rsc/scripts/jsdoc/test/fixtures/destructuring.js deleted file mode 100644 index 2b13f928..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/destructuring.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - A builder function for the Stick application; - @var {function} Application - */ -var {Application} = require("stick"); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/doclet.js b/rsc/scripts/jsdoc/test/fixtures/doclet.js deleted file mode 100644 index abba2473..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/doclet.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - Markdown asterisks in a doclet that does not use leading asterisks. - **Strong** is strong. - - * List item 1. - * List item 2. - @param {string} thingy - The thingy. - */ -function test1(thingy) { - -} - -/** - * Markdown asterisks in a doclet that uses leading asterisks. - * **Strong** is strong. - * - * * List item 1. - * * List item 2. - * @param {string} thingy - The thingy. - */ -function test2(thingy) { - -} diff --git a/rsc/scripts/jsdoc/test/fixtures/enumtag.js b/rsc/scripts/jsdoc/test/fixtures/enumtag.js deleted file mode 100644 index 2374f09e..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/enumtag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Enum for tri-state values. - * @enum {number} - */ -var TriState = { - /** true */ - TRUE: 1, - FALSE: -1, - /** @type {boolean} */ - MAYBE: true -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/eventfirestag.js b/rsc/scripts/jsdoc/test/fixtures/eventfirestag.js deleted file mode 100644 index 331eaf8c..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/eventfirestag.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @class - */ -var Hurl = function () { -}; - -/** - * Throw a snowball. - * - * @fires Hurl#snowball - * @fires Hurl#event:brick - */ -Hurl.prototype.snowball = function () { - /** - * @event Hurl#snowball - */ - this.emit('snowball', {}); -}; - -/** - * Throw a football match. - * - * @emits Hurl#footballMatch - */ -Hurl.prototype.footballMatch = function () { - /** - * @event Hurl#footballMatch - */ - this.emit('footballMatch', {}); -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/exampletag.js b/rsc/scripts/jsdoc/test/fixtures/exampletag.js deleted file mode 100644 index b20f7530..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exampletag.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @example - * console.log("foo"); - * console.log("bar"); - */ -var x; - -/** @example - * console.log("foo"); - * console.log("bar"); - * @example - * Example 2 - * 1 + 2; - */ -var y; diff --git a/rsc/scripts/jsdoc/test/fixtures/exceptiontag.js b/rsc/scripts/jsdoc/test/fixtures/exceptiontag.js deleted file mode 100644 index 14d7d9a7..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exceptiontag.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - @throws {InvalidArgumentException} -*/ -function foo(x) { - -} - -/** - @exception Will throw an error if argument is null. -*/ -function bar(x) { - -} - -/** - @exception {DivideByZero} Argument x must be non-zero. -*/ -function pez(x) { - -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/exports.js b/rsc/scripts/jsdoc/test/fixtures/exports.js deleted file mode 100644 index 9c132478..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exports.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * An example of a server-side JavaScript module. - * @module hello/world - * @example - * var g = require('hello/world').sayHello('Gracie'); - */ - -/** - * Generate a greeting. - * @param {string} [subject="world"] To whom we greet. - * @returns {string} - */ -exports.sayHello = function(subject) { - return 'Hello ' + (subject || 'World'); -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/exportstag.js b/rsc/scripts/jsdoc/test/fixtures/exportstag.js deleted file mode 100644 index 26f787ea..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exportstag.js +++ /dev/null @@ -1,20 +0,0 @@ -define(function () { - /** - A module representing a shirt. - @exports my/shirt - @version 1.0 - */ - var shirt = { - - /** A property of the module. */ - color: "black", - - /** @constructor */ - Turtleneck: function(size) { - /** A property of the class. */ - this.size = size; - } - }; - - return shirt; -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/exportstag2.js b/rsc/scripts/jsdoc/test/fixtures/exportstag2.js deleted file mode 100644 index 5e00268a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exportstag2.js +++ /dev/null @@ -1,18 +0,0 @@ -define( - ["my/buttons"], - function () { - /** - A module representing a coat. - @exports my/coat - @requires my/buttons - @version 1.0 - */ - var myModule = function(wool) { - /** document me */ - this.wool = wool; - } - - return myModule; - - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/exportstag3.js b/rsc/scripts/jsdoc/test/fixtures/exportstag3.js deleted file mode 100644 index d48e94e2..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exportstag3.js +++ /dev/null @@ -1,22 +0,0 @@ -define( - /** - Utility functions to ease working with DOM elements. - @exports html/utils - */ - function () { - - var exports = { - /** Get the value of a property on an element. */ - getStyleProperty: function(element, propertyName) { - // ... - } - }; - - /** Determine if an element is in the document head. */ - exports.isInHead = function(element) { - // ... - } - - return exports; - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/exportstag4.js b/rsc/scripts/jsdoc/test/fixtures/exportstag4.js deleted file mode 100644 index 3097a565..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/exportstag4.js +++ /dev/null @@ -1,12 +0,0 @@ -define( - /** @exports some/module */ - function () { - /** @class */ - function myClass() {} - - /** Some method */ - myClass.prototype.myMethod = function () {}; - - return new myClass(); - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/externals.js b/rsc/scripts/jsdoc/test/fixtures/externals.js deleted file mode 100644 index 6a8dd030..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/externals.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * The built in string object. - * @external String - * @see {@link https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String String} - */ - -/** - * Adds a new method to the built-in string. - * @function external:String#rot13 - * @example - * var greeting = new String('hello world'); - * console.log( greeting.rot13() ); // uryyb jbeyq - */ - -/** - * The jQuery plugin namespace. - * @external "jQuery.fn" - * @see {@link http://docs.jquery.com/Plugins/Authoring The jQuery Plugin Guide} - */ - -/** - * A jQuery plugin to make stars fly around your home page. - * @function external:"jQuery.fn".starfairy - */ diff --git a/rsc/scripts/jsdoc/test/fixtures/externals2.js b/rsc/scripts/jsdoc/test/fixtures/externals2.js deleted file mode 100644 index 0099f0c1..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/externals2.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - Namespace provided by the browser. - @external XMLHttpRequest - @see https://developer.mozilla.org/en/xmlhttprequest - */ - -/** - Extends the built in XMLHttpRequest to send data encoded with a secret key. - @class EncryptedRequest - @extends external:XMLHttpRequest -*/ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/file.js b/rsc/scripts/jsdoc/test/fixtures/file.js deleted file mode 100644 index e6d62cdc..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/file.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @overview This is a file doclet. - * @copyright Michael Mathews 2011 - */ - -function ignoreMe() { -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/functiontag.js b/rsc/scripts/jsdoc/test/fixtures/functiontag.js deleted file mode 100644 index 9783268f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/functiontag.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @func Foo */ -function Foo() { -} - -/** @method */ -function Bar() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/getset.js b/rsc/scripts/jsdoc/test/fixtures/getset.js deleted file mode 100644 index 34a362f3..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/getset.js +++ /dev/null @@ -1,37 +0,0 @@ -/** @class */ -var Person = makeClass( - /** @lends Person# */ - { - /** Set up initial values. */ - initialize: function(name) { - }, - - /** Speak a message. */ - say: function(message) { - return this.name + " says: " + message; - }, - - /** - * The name of the person. - * @type {string} - */ - get name() { - return this._name; - }, - - /** - * @type {string} - * @param val - */ - set name(val) { - this._name = name; - }, - - /** - * @type {number} - */ - get age() { - return 25; - } - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/globaltag.js b/rsc/scripts/jsdoc/test/fixtures/globaltag.js deleted file mode 100644 index 44f1d186..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/globaltag.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - @global - @constructor - */ -window.Bar = new Function('', a, b, c); - -(function() { - - /** @global */ - var foo; - - foo = 'hello foo'; - - this.foo = foo; - -}).apply(window); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/ignoretag.js b/rsc/scripts/jsdoc/test/fixtures/ignoretag.js deleted file mode 100644 index 4e8c2121..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/ignoretag.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - @ignore -*/ -function foo(x) { - -} diff --git a/rsc/scripts/jsdoc/test/fixtures/ignoretag2.js b/rsc/scripts/jsdoc/test/fixtures/ignoretag2.js deleted file mode 100644 index 43db1b49..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/ignoretag2.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - @ignore value that shouldn't be here -*/ -function foo(x) { - -} diff --git a/rsc/scripts/jsdoc/test/fixtures/include.js b/rsc/scripts/jsdoc/test/fixtures/include.js deleted file mode 100644 index 1e76887f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/include.js +++ /dev/null @@ -1,3 +0,0 @@ -// Used to test jsdoc/util/include -var myGlobal = require('jsdoc/util/global'); -myGlobal.__globalForIncludeTest__++; diff --git a/rsc/scripts/jsdoc/test/fixtures/inlinecomment.js b/rsc/scripts/jsdoc/test/fixtures/inlinecomment.js deleted file mode 100644 index 883d5f0b..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/inlinecomment.js +++ /dev/null @@ -1,2 +0,0 @@ -/** Inline Comment 1 */ this.test = function(){} -/** Inline Comment 2 */ this.test2 = function(){}; diff --git a/rsc/scripts/jsdoc/test/fixtures/inner.js b/rsc/scripts/jsdoc/test/fixtures/inner.js deleted file mode 100644 index 4c07b97a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/inner.js +++ /dev/null @@ -1,7 +0,0 @@ -function sendMessage(text) { - /** document me */ - var encoding = 'utf8'; - - /** document me */ - function encrypt(){} -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/innerscope.js b/rsc/scripts/jsdoc/test/fixtures/innerscope.js deleted file mode 100644 index 5d2d5f5c..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/innerscope.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @constructor */ -function Message(to) { - - var headers = {}, - response; - - /** document me */ - headers.to = to; - - (function() { - /** document me */ - response.code = '200'; - - /** document me */ - headers.from = ''; - })() -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/innerscope2.js b/rsc/scripts/jsdoc/test/fixtures/innerscope2.js deleted file mode 100644 index 68f30cba..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/innerscope2.js +++ /dev/null @@ -1,19 +0,0 @@ -/** @constructor */ -function Message(to) { - - var headers = {}; - - /** document me */ - headers.to = to; - - (function() { - var headers = { - /** document me */ - cache: {} - }; - - /** document me */ - headers.from = ''; - })() -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/jshint/badfile.js b/rsc/scripts/jsdoc/test/fixtures/jshint/badfile.js deleted file mode 100644 index 1f1042b3..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/jshint/badfile.js +++ /dev/null @@ -1,3 +0,0 @@ -foo(); - -function foo() {} diff --git a/rsc/scripts/jsdoc/test/fixtures/jshint/goodfile.js b/rsc/scripts/jsdoc/test/fixtures/jshint/goodfile.js deleted file mode 100644 index 6c42f3b5..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/jshint/goodfile.js +++ /dev/null @@ -1 +0,0 @@ -var foo = 0; diff --git a/rsc/scripts/jsdoc/test/fixtures/jslangnames.js b/rsc/scripts/jsdoc/test/fixtures/jslangnames.js deleted file mode 100644 index 65f8404a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/jslangnames.js +++ /dev/null @@ -1,24 +0,0 @@ - -/** @namespace */ -var constructor = { - /** document me */ - toString: function(){} -}; - -/** @namespace */ -var prototye = { - /** document me */ - valueOf: function(){} -} - -/** - This is Object - @namespace Object -*/ - -/** - This is Object.hasOwnProperty - @method Object.hasOwnProperty - */ - -// NOTE: you can't document a prototype of an object in JSDoc -- seriously, you just can't \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/kindtag.js b/rsc/scripts/jsdoc/test/fixtures/kindtag.js deleted file mode 100644 index 72c5682f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/kindtag.js +++ /dev/null @@ -1,2 +0,0 @@ -/** @kind function */ -var x; diff --git a/rsc/scripts/jsdoc/test/fixtures/lends.js b/rsc/scripts/jsdoc/test/fixtures/lends.js deleted file mode 100644 index 6d86ae6d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/lends.js +++ /dev/null @@ -1,16 +0,0 @@ -/** @class */ -var Person = makeClass( - /** @lends Person# */ - { - /** Set up initial values. */ - initialize: function(name) { - /** The name of the person. */ - this.name = name; - }, - - /** Speak a message. */ - say: function(message) { - return this.name + " says: " + message; - } - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/lends2.js b/rsc/scripts/jsdoc/test/fixtures/lends2.js deleted file mode 100644 index 57c4fa38..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/lends2.js +++ /dev/null @@ -1,18 +0,0 @@ - -var Person = makeClass( - /** @lends Person# */ - { - /** Construct a Person. - @constructs Person - */ - initialize: function(name) { - /** The name of the person. */ - this.name = name; - }, - - /** Speak a message. */ - say: function(message) { - return this.name + " says: " + message; - } - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/lends3.js b/rsc/scripts/jsdoc/test/fixtures/lends3.js deleted file mode 100644 index 13c11a31..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/lends3.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @class */ -var Person = makeClass( - /** - * @lends Person# - */ - { - /** Set up initial values. */ - initialize: function(name) { - /** The name of the person. */ - this.name = name; - }, - - /** Speak a message. */ - say: function(message) { - return this.name + " says: " + message; - } - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/lendsglobal.js b/rsc/scripts/jsdoc/test/fixtures/lendsglobal.js deleted file mode 100644 index 13803be1..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/lendsglobal.js +++ /dev/null @@ -1,14 +0,0 @@ -declare({ - globals: /** @lends */ { - - /** document me */ - 'test': function() { }, - - /** @namespace */ - 'test1': { - - /** document me */ - 'test2': function() { } - } - } -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/licensetag.js b/rsc/scripts/jsdoc/test/fixtures/licensetag.js deleted file mode 100644 index e9d852f5..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/licensetag.js +++ /dev/null @@ -1,2 +0,0 @@ -/** @license GPL v2 */ -var x; diff --git a/rsc/scripts/jsdoc/test/fixtures/linktag.js b/rsc/scripts/jsdoc/test/fixtures/linktag.js deleted file mode 100644 index 6f23ff1f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/linktag.js +++ /dev/null @@ -1,15 +0,0 @@ -/** @namespace ns */ -var ns = {}; - -/** -* Similar to [the bar function]{@link bar}. -* @see {@link bar} -*/ -ns.foo = function () { -} - -/** -* @see {@link ns.foo} -*/ -function bar() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/listenstag.js b/rsc/scripts/jsdoc/test/fixtures/listenstag.js deleted file mode 100644 index 50f82da3..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/listenstag.js +++ /dev/null @@ -1,34 +0,0 @@ -/** @module myModule */ - -/** An event (has listeners). - * @event MyEvent - * @memberof module:myModule - * @param {number} foo - asdf. */ - -/** A handler. - * @listens module:myModule.MyEvent - * @listens module:myModule~Events.event:Event2 - * @listens fakeEvent - */ -function MyHandler() { -} - -/** Another handler. - * @listens module:myModule.MyEvent - */ -function AnotherHandler() { -} - -/** a namespace. - * @namespace */ -var Events = { -}; - -/** Another event (has listeners). - * @event Event2 - * @memberof module:myModule~Events - */ - -/** An event with no listeners. - * @event module:myModule#Event3 */ - diff --git a/rsc/scripts/jsdoc/test/fixtures/markdowntest.md b/rsc/scripts/jsdoc/test/fixtures/markdowntest.md deleted file mode 100644 index 276aada8..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/markdowntest.md +++ /dev/null @@ -1,10 +0,0 @@ -This is a header ----- - -This is some text. - - this is some code - -* this -* a -* list \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/memberoftag.js b/rsc/scripts/jsdoc/test/fixtures/memberoftag.js deleted file mode 100644 index 27993933..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/memberoftag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @constructor - @memberof mathlib - */ -function Data() { - - /** @member */ - this.point = {}; -} - -/** @namespace */ -mathlib = {Data: Data}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/memberoftag2.js b/rsc/scripts/jsdoc/test/fixtures/memberoftag2.js deleted file mode 100644 index b926dc6a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/memberoftag2.js +++ /dev/null @@ -1,10 +0,0 @@ -create( - 'Observable', - { - /** @memberof Observable */ - cache: [], - - /** @memberof Observable.prototype */ - publish: function(msg) {} - } -); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/memberoftag3.js b/rsc/scripts/jsdoc/test/fixtures/memberoftag3.js deleted file mode 100644 index a19f1357..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/memberoftag3.js +++ /dev/null @@ -1,19 +0,0 @@ -/** @module terrain - @example - var terrain = require('terrain'), - forest = new terrain.Forest(), - tree = new forest.Tree(); -*/ - -/** @class */ -exports.Forest = function(){} -var Forest = exports.Forest; - -/** - @class - @memberof module:terrain -*/ -Forest.prototype.Tree = function() { - /** A leaf */ - this.leaf = 1; -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/memberoftag4.js b/rsc/scripts/jsdoc/test/fixtures/memberoftag4.js deleted file mode 100644 index 521343d8..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/memberoftag4.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Namespace doStuff. - * @namespace doStuff - */ - -/** - * Function with the same name as its namespace. - * @memberof doStuff - */ -function doStuff() {} - -/** - * Function with a different name than the namespace. - * @memberof doStuff - */ -function doOtherStuff() {} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/memberoftagforced.js b/rsc/scripts/jsdoc/test/fixtures/memberoftagforced.js deleted file mode 100644 index c1b495de..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/memberoftagforced.js +++ /dev/null @@ -1,44 +0,0 @@ - - /** @constructor - */ - function Data() { - - /** - The current position. - @type {object} - @property {boolean} needsRevalidate Does this point need to be revalidated? - */ - this.point = { - /** - The x coordinate of the point. - @type {number} - @name point.x - @memberof! Data# - */ - x: 0, - - /** - The y coordinate of the point. - @type {number} - @name point.y - @memberof! Data# - @see {@link Data#point.x} - */ - y: 0, - - needsRevalidate: false - }; - } - -var map = { - /** - @type {Array} - @name map.routes - @memberof! - @property {Data#point} point - */ - routes: [] -} - -/** The current cursor. */ -var cursor = {}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/membertag.js b/rsc/scripts/jsdoc/test/fixtures/membertag.js deleted file mode 100644 index 66aee08d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/membertag.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @member */ -var x; - -/** @var foobar */ -/** @var {string} baz */ diff --git a/rsc/scripts/jsdoc/test/fixtures/mixintag.js b/rsc/scripts/jsdoc/test/fixtures/mixintag.js deleted file mode 100644 index 07dc085d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/mixintag.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This provides methods used for event handling. It's not meant to - * be used directly, except as a provider of related methods. - * - * @mixin - */ -var Eventful = { - /** fires something. */ - fires: function () {}, - /** handles a signal. */ - on: function () {} -}; - -/** - * @constructor - * @mixes Eventful - */ -var FormButton = function() { -}; - -/** @mixin AnotherMixin*/ - -/** I mix in multiple things - * @constructor MyClass - * @mixes Eventful - * @mixes AnotherMixin */ - diff --git a/rsc/scripts/jsdoc/test/fixtures/moduleinner.js b/rsc/scripts/jsdoc/test/fixtures/moduleinner.js deleted file mode 100644 index 7f2d0a3f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/moduleinner.js +++ /dev/null @@ -1,28 +0,0 @@ -/** -* @module my/module -*/ -(function() { - -/** document fooIn */ -fooIn = function() { -}; - -/** @namespace */ -bar = { - /** document bar.Zop */ - zop: function() { - } -} - -/** @constructor */ -exports.Frotz = function() { - /** document exports.Frotz#quaz */ - this.quaz = 1; -} - -}) (); - -/** document fooOut -*/ -fooOut = function() { -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/moduleisconstructor.js b/rsc/scripts/jsdoc/test/fixtures/moduleisconstructor.js deleted file mode 100644 index 1990d7f7..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/moduleisconstructor.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - Describe the module here. - @module mymodule/config -*/ - -/** - Create a new configuration - @param {string} id - @constructor - @alias module:mymodule/config -*/ -function Config(id) { - /** Document me. */ - this.id = id; -} - -module.exports = Config; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/moduleisfunction.js b/rsc/scripts/jsdoc/test/fixtures/moduleisfunction.js deleted file mode 100644 index 21c29bda..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/moduleisfunction.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * This is a module called foo. - * @module foo - */ - -/** - * The module exports a single function. - * @param {string} bar - */ -module.exports = function(bar) {}; diff --git a/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-1.js b/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-1.js deleted file mode 100644 index a5de108f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-1.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @module */ -define({ - property: "foo", - method: function() {} -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-2.js b/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-2.js deleted file mode 100644 index 1027fd9d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-2.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @module my/module/name */ -define({ - property: "foo", - method: function() {} -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-3.js b/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-3.js deleted file mode 100644 index 91a3251a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/modules/data/mod-3.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - My test module. - @module my/module - */ -define(function() { - - /** - @undocumented - @alias module:my/module - */ - var mod = { - - /** Document a property. */ - myProperty: "foo", - - /** Document a method. */ - myMethod: function() {} - }; - - return mod; -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/moduletag.js b/rsc/scripts/jsdoc/test/fixtures/moduletag.js deleted file mode 100644 index fb4c4665..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/moduletag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @module bookshelf - */ - -/** - * @class - */ -this.Book = function(title) { - /** document me */ - this.title = title; -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/moduletag2.js b/rsc/scripts/jsdoc/test/fixtures/moduletag2.js deleted file mode 100644 index 0dd0bc3e..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/moduletag2.js +++ /dev/null @@ -1,9 +0,0 @@ -/** @module color/mixer */ - -module.exports = { - /** Blend two colors together. */ - blend: function(color1, color2) { } -} - -/** Darken a color by the given shade. */ -exports.darken = function(color, shade) { } \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/moduletag3.js b/rsc/scripts/jsdoc/test/fixtures/moduletag3.js deleted file mode 100644 index d3b635b0..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/moduletag3.js +++ /dev/null @@ -1,20 +0,0 @@ -/** -@module foo/Photo/manager -@desc Manage a collection of photos. -*/ - -/** -Construct a new Photo manager -@constructor module:foo/Photo/manager -@param {String} collectionId The identifier of the managed collection. -*/ -module.exports = function(collectionId) { - - /** - @function module:foo/Photo/manager#getPhoto - @param {String} photoName - */ - this.getPhoto = function() {} - -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement.js b/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement.js deleted file mode 100644 index 924a659f..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @class */ -var Foo = function Bar(a) { - /** document me */ - var var1 = 1; - /** document me */ - this.member1 = 2; -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement2.js b/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement2.js deleted file mode 100644 index 0223092a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement2.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @class */ -Foo = function Bar(a) { - /** document me */ - var var1 = 1; - /** document me */ - this.member1 = 2; -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement3.js b/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement3.js deleted file mode 100644 index 8f185816..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/namedFuncStatement3.js +++ /dev/null @@ -1,9 +0,0 @@ -ns = { - /** @class */ - Foo: function Bar(a) { - /** document me */ - var var1 = 1; - /** document me */ - this.member1 = 2; - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/namespacetag.js b/rsc/scripts/jsdoc/test/fixtures/namespacetag.js deleted file mode 100644 index 82dc1081..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/namespacetag.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @namespace */ -var x = { -}; -/** @namespace Foo */ -/** @namespace {function} Bar */ diff --git a/rsc/scripts/jsdoc/test/fixtures/objectlit.js b/rsc/scripts/jsdoc/test/fixtures/objectlit.js deleted file mode 100644 index f976cfb4..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/objectlit.js +++ /dev/null @@ -1,8 +0,0 @@ -/** document me */ -var tools = { - /** document me */ - serialiser: { - /** document me */ - value: '' - } -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/objectlit2.js b/rsc/scripts/jsdoc/test/fixtures/objectlit2.js deleted file mode 100644 index 072d4eda..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/objectlit2.js +++ /dev/null @@ -1,8 +0,0 @@ -/** document me */ -var position = { - axis: { - /** document me */ - x: 0, - y: 0 - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/objectpropertykeys.js b/rsc/scripts/jsdoc/test/fixtures/objectpropertykeys.js deleted file mode 100644 index abc611f2..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/objectpropertykeys.js +++ /dev/null @@ -1,22 +0,0 @@ -Call( -{ - methodA: function() - { - this.id = this.createUUID(); - }, - - valueOf: function() - { - return this.id; - }, - - toString: function() - { - return this.id; - } -}); - -//Simple inheritance model with correct constructor -function Test() {} -function Test2() { Test.call(this); } -Test2.prototype = Object.create(Test.prototype, {constructor: {value: Test2}}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/paramtag.js b/rsc/scripts/jsdoc/test/fixtures/paramtag.js deleted file mode 100644 index c6fd831c..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/paramtag.js +++ /dev/null @@ -1,47 +0,0 @@ -/** -* @param { String | Array} targetName The name (or names) of what to find. -*/ -function find(targetName) { -} - -/** -* @param {function} callback -*/ -function bind(callback) { -} - -/** -* @param {function} -*/ -function unbind(callback) { -} - -/** -* @param id The id of the element. -*/ -function getElement(id) { -} - -/** -* @param ... Two or more elements. -*/ -function combine() { -} - -/** -* @param delimiter - What to split on. -*/ -function split(delimiter) { -} - -/** -* @param - If true make the commit atomic. -*/ -function commit(atomic) { -} - -/** - * @param [async=true] - whether to be asynchronous - */ -function request(async) { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/plugins.js b/rsc/scripts/jsdoc/test/fixtures/plugins.js deleted file mode 100644 index d71e6e9d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/plugins.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @name virtual - */ - -var foo = "bar"; - -/** - * @foo bar - */ -var test = "tada"; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/privatetag.js b/rsc/scripts/jsdoc/test/fixtures/privatetag.js deleted file mode 100644 index 71e0d971..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/privatetag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** -* @constructor -* @private -*/ -function Foo() { - - /** document me */ - this.bar = 1; -} - - diff --git a/rsc/scripts/jsdoc/test/fixtures/projecttag.js b/rsc/scripts/jsdoc/test/fixtures/projecttag.js deleted file mode 100644 index b00c8e2c..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/projecttag.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - An automated documentation generator for JavaScript. - @project JSDoc - @version 3.0.0 - @copyright 2011 (c) Michael Mathews - @license Apache Version 2 - */ -function blah(url) { -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/propertytag.js b/rsc/scripts/jsdoc/test/fixtures/propertytag.js deleted file mode 100644 index 475fe31b..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/propertytag.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @namespace - * @property {Object} defaults The default values. - * @property {Number} defaults.a The a property of the defaults. - * @property {String} defaults.b The b property of the defaults. - */ -myobject = { - defaults: { - a: 1, - b: "Hit the light", - c: true - } -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/quotename.js b/rsc/scripts/jsdoc/test/fixtures/quotename.js deleted file mode 100644 index aa7577c1..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/quotename.js +++ /dev/null @@ -1,19 +0,0 @@ -/** @namespace */ -var chat = {}; - -/** - @namespace - */ -chat["#channel"] = {}; - - -/** - @member - @type {boolean} - @defaultvalue - */ -chat["#channel"].open = true; - -/** - @event chat."#channel"."op:announce-motd" - */ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/quotename2.js b/rsc/scripts/jsdoc/test/fixtures/quotename2.js deleted file mode 100644 index b05c8136..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/quotename2.js +++ /dev/null @@ -1,10 +0,0 @@ -/** @namespace */ -var contacts = { - - /** @namespace */ - 'say-"hello"@example.com': { - - /** document me */ - "username": 'Sue Smart' - } -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/readonlytag.js b/rsc/scripts/jsdoc/test/fixtures/readonlytag.js deleted file mode 100644 index 30e826ce..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/readonlytag.js +++ /dev/null @@ -1,10 +0,0 @@ -/** -* @constructor -*/ -function Collection() { - - /** @readonly */ - this.length = 0; -} - - diff --git a/rsc/scripts/jsdoc/test/fixtures/requirestag.js b/rsc/scripts/jsdoc/test/fixtures/requirestag.js deleted file mode 100644 index 3fe27229..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/requirestag.js +++ /dev/null @@ -1,12 +0,0 @@ -/** -* @requires module:foo/helper -*/ -function foo() { -} - -/** -* @requires foo -* @requires Pez#blat this text is ignored -*/ -function bar() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/returnstag.js b/rsc/scripts/jsdoc/test/fixtures/returnstag.js deleted file mode 100644 index d3cf4de4..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/returnstag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** -* @returns { String | Array} The names of the found item(s). -*/ -function find(targetName) { -} - -/** -* @return The binding id. -*/ -function bind(callback) { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/scopetags.js b/rsc/scripts/jsdoc/test/fixtures/scopetags.js deleted file mode 100644 index 1eeeb204..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/scopetags.js +++ /dev/null @@ -1,10 +0,0 @@ -/** (scope tags for global objects do not override globalness hence need a container class) - * @module scopetags */ -/** @inner */ -var myInner; - -/** @instance */ -var myInstance; - -/** @static */ -var myStatic; diff --git a/rsc/scripts/jsdoc/test/fixtures/seetag.js b/rsc/scripts/jsdoc/test/fixtures/seetag.js deleted file mode 100644 index b439c261..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/seetag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** -* @see {@link bar} -*/ -function foo() { -} - -/** -* @see http://example.com/someref -*/ -function bar() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/sincetag.js b/rsc/scripts/jsdoc/test/fixtures/sincetag.js deleted file mode 100644 index 527b2a39..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/sincetag.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - @since 1.2.3 -*/ -function foo(x) { - -} diff --git a/rsc/scripts/jsdoc/test/fixtures/specialnames.js b/rsc/scripts/jsdoc/test/fixtures/specialnames.js deleted file mode 100644 index d775a0b1..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/specialnames.js +++ /dev/null @@ -1,2 +0,0 @@ -/** document me */ -var hasOwnProperty = Object.prototype.hasOwnProperty; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/src/_dir2/four.js b/rsc/scripts/jsdoc/test/fixtures/src/_dir2/four.js deleted file mode 100644 index e69de29b..00000000 diff --git a/rsc/scripts/jsdoc/test/fixtures/src/_ignored.js b/rsc/scripts/jsdoc/test/fixtures/src/_ignored.js deleted file mode 100644 index e69de29b..00000000 diff --git a/rsc/scripts/jsdoc/test/fixtures/src/dir1/three.js b/rsc/scripts/jsdoc/test/fixtures/src/dir1/three.js deleted file mode 100644 index e69de29b..00000000 diff --git a/rsc/scripts/jsdoc/test/fixtures/src/ignored.txt b/rsc/scripts/jsdoc/test/fixtures/src/ignored.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/rsc/scripts/jsdoc/test/fixtures/src/one.js b/rsc/scripts/jsdoc/test/fixtures/src/one.js deleted file mode 100644 index e69de29b..00000000 diff --git a/rsc/scripts/jsdoc/test/fixtures/src/two.js b/rsc/scripts/jsdoc/test/fixtures/src/two.js deleted file mode 100644 index e69de29b..00000000 diff --git a/rsc/scripts/jsdoc/test/fixtures/starbangstar.js b/rsc/scripts/jsdoc/test/fixtures/starbangstar.js deleted file mode 100644 index 262da969..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/starbangstar.js +++ /dev/null @@ -1,12 +0,0 @@ -/*!* -* Script that does something awesome -* -* @copyright (c) 2011 Rotorz Limited. All rights reserved. -* @author Lea Hayes -* @module myscript/core -*/ - -/*!********************************* - * This should be ignored by JSDoc - * @var x - */ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/summarytag.js b/rsc/scripts/jsdoc/test/fixtures/summarytag.js deleted file mode 100644 index b1f4c496..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/summarytag.js +++ /dev/null @@ -1,3 +0,0 @@ -/** @summary I do not like green eggs and ham! */ -function Sam() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/testPlugin1.js b/rsc/scripts/jsdoc/test/fixtures/testPlugin1.js deleted file mode 100644 index 3b3e26b7..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/testPlugin1.js +++ /dev/null @@ -1,39 +0,0 @@ -var myGlobal = require('jsdoc/util/global'); -myGlobal.jsdocPluginsTest.plugin1 = {}; - -exports.handlers = { - fileBegin: function() { - myGlobal.jsdocPluginsTest.plugin1.fileBegin = true; - }, - beforeParse: function() { - myGlobal.jsdocPluginsTest.plugin1.beforeParse = true; - }, - jsdocCommentFound: function() { - myGlobal.jsdocPluginsTest.plugin1.jsdocCommentFound = true; - }, - symbolFound: function() { - myGlobal.jsdocPluginsTest.plugin1.symbolFound = true; - }, - newDoclet: function() { - myGlobal.jsdocPluginsTest.plugin1.newDoclet = true; - }, - fileComplete: function() { - myGlobal.jsdocPluginsTest.plugin1.fileComplete = true; - } -}; - -exports.defineTags = function(dictionary) { - dictionary.defineTag("foo", { - canHaveName: true, - onTagged: function(doclet, tag) { - doclet.foo = true; - } - }); -}; - -exports.nodeVisitor = { - visitNode: function(node, e, parser, currentSourceName) { - myGlobal.jsdocPluginsTest.plugin1.visitNode = true; - e.stopPropagation = true; - } -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/testPlugin2.js b/rsc/scripts/jsdoc/test/fixtures/testPlugin2.js deleted file mode 100644 index bd7189f4..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/testPlugin2.js +++ /dev/null @@ -1,29 +0,0 @@ -var myGlobal = require('jsdoc/util/global'); -myGlobal.jsdocPluginsTest.plugin2 = {}; - -exports.handlers = { - fileBegin: function() { - myGlobal.jsdocPluginsTest.plugin2.fileBegin = true; - }, - beforeParse: function() { - myGlobal.jsdocPluginsTest.plugin2.beforeParse = true; - }, - jsdocCommentFound: function() { - myGlobal.jsdocPluginsTest.plugin2.jsdocCommentFound = true; - }, - symbolFound: function() { - myGlobal.jsdocPluginsTest.plugin2.symbolFound = true; - }, - newDoclet: function() { - myGlobal.jsdocPluginsTest.plugin2.newDoclet = true; - }, - fileComplete: function() { - myGlobal.jsdocPluginsTest.plugin2.fileComplete = true; - } -}; - -exports.nodeVisitor = { - visitNode: function() { - myGlobal.jsdocPluginsTest.plugin2.visitNode = true; - } -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/this-and-objectlit.js b/rsc/scripts/jsdoc/test/fixtures/this-and-objectlit.js deleted file mode 100644 index 37b3c94a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/this-and-objectlit.js +++ /dev/null @@ -1,12 +0,0 @@ -/** @constructor */ -function Page(title) { - this.parts = { - title: title, - body: { - /** document me */ - heading: '', - main: '' - } - }; -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/this.js b/rsc/scripts/jsdoc/test/fixtures/this.js deleted file mode 100644 index 7c167606..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/this.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - @constructor - */ -function Singer() { - - this.tralala = function() { // method of constructor Singer - /** document me */ - this.isSinging = true; // setting a member of constructor Singer - }; -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/this2.js b/rsc/scripts/jsdoc/test/fixtures/this2.js deleted file mode 100644 index 88fd9fa6..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/this2.js +++ /dev/null @@ -1,15 +0,0 @@ -/** @constructor */ -function TemplateBuilder(templateType) { - //** document me */ - //this.templateType = templateType; - - /** @constructor */ - this.Template = function() { // nested constructor of constructor TemplateFactory - /** document me */ - this.render = function(data) { - /** document me */ - this.rendered = true; - } - }; - -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/this3.js b/rsc/scripts/jsdoc/test/fixtures/this3.js deleted file mode 100644 index 7e4e0a77..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/this3.js +++ /dev/null @@ -1,5 +0,0 @@ -function setPosition(newP) { - /** document me */ - this.position = newP; // sets global property -} - diff --git a/rsc/scripts/jsdoc/test/fixtures/thistag.js b/rsc/scripts/jsdoc/test/fixtures/thistag.js deleted file mode 100644 index 1ea79253..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/thistag.js +++ /dev/null @@ -1,10 +0,0 @@ -/** @constructor */ -function Foo(name) { - setName.apply(this, name); -} - -/** @this Foo */ -function setName(name) { - /** document me */ - this.name = name; -} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/todotag.js b/rsc/scripts/jsdoc/test/fixtures/todotag.js deleted file mode 100644 index 5ecfac4b..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/todotag.js +++ /dev/null @@ -1,6 +0,0 @@ -/** A function. - * @todo something - * @todo something else - */ -function x() { -} diff --git a/rsc/scripts/jsdoc/test/fixtures/tutorialtag.js b/rsc/scripts/jsdoc/test/fixtures/tutorialtag.js deleted file mode 100644 index b0124dbe..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/tutorialtag.js +++ /dev/null @@ -1,5 +0,0 @@ -/** Some documentation. - * @tutorial tute1 - * @tutorial tute2 - */ -var x; diff --git a/rsc/scripts/jsdoc/test/fixtures/typedeftag.js b/rsc/scripts/jsdoc/test/fixtures/typedeftag.js deleted file mode 100644 index fa2b0890..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/typedeftag.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @typedef {(string|number)} calc.NumberLike */ - -/** @typedef {string} */ -calc.Operator; - -/** @typedef {calc.NumberLike} calc.Result */ -calc.Outcome; - -/** @param {calc.NumberLike} x A number or a string. */ -calc.readNumber = function(x) { -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/typekind.js b/rsc/scripts/jsdoc/test/fixtures/typekind.js deleted file mode 100644 index 46d6c1eb..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/typekind.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - @module {ConnectServer} blog/server -*/ - -module.exports = require('connect').createServer( - Connect.logger(), - Connect.conditionalGet(), - Connect.favicon(), - Connect.cache(), - Connect.gzip(), - require('wheat')(__dirname) -); - -/** - @member {number} module:blog/server.port - @default 8080 -*/ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/typetag.js b/rsc/scripts/jsdoc/test/fixtures/typetag.js deleted file mode 100644 index acaa7cac..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/typetag.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - @type {string|Array} -*/ -var foo; - - -/** - @type integer -*/ -var bar = +(new Date()).getTime(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/undocumentedtag.js b/rsc/scripts/jsdoc/test/fixtures/undocumentedtag.js deleted file mode 100644 index 01ab4fc3..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/undocumentedtag.js +++ /dev/null @@ -1,3 +0,0 @@ -/** Undocumented doclet. - * @undocumented */ -var x; diff --git a/rsc/scripts/jsdoc/test/fixtures/utf8.js b/rsc/scripts/jsdoc/test/fixtures/utf8.js deleted file mode 100644 index ec6eea74..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/utf8.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @constructor - * @desc Τεκμηρίωση είναι η επικοινωνία! - */ -Test = function() { -}; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/var.js b/rsc/scripts/jsdoc/test/fixtures/var.js deleted file mode 100644 index 0daea9f5..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/var.js +++ /dev/null @@ -1,10 +0,0 @@ -/** document me */ -const GREEN = 1, - RED = 0; - -/** document me */ -var validate = function(){}; - -var i, - /** document me */ - results; \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/variations.js b/rsc/scripts/jsdoc/test/fixtures/variations.js deleted file mode 100644 index e292cae7..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/variations.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @namespace anim - */ - -/** - * @method anim.fadein(1) - * @desc Show the nodelist elements by fading them to opaque. - * @since 1.0 - * - * @param {number} [duration=400] How long the animation will run. - * @param {function} [callback] Called once the animation is complete. - * - * @returns {this} - */ - -/** - * @method anim.fadein(2) - * @desc Show the nodelist elements by fading them to opaque. - * @since 1.4.3 - * - * @param {number} [duration=400] How long the animation will run. - * @param {string} [easing=swing] The easing function for the transition. - * @param {function} [callback] Called once the animation is complete. - * - * @returns {this} - */ \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/variations2.js b/rsc/scripts/jsdoc/test/fixtures/variations2.js deleted file mode 100644 index 2105c463..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/variations2.js +++ /dev/null @@ -1,36 +0,0 @@ -/** -* Describe the namespace. -* @namespace dollar(1) -*/ - -/** -* Describe the constructor. -* @constructor dollar(2) -* @param {object} [options] -*/ - -/** -* Describe the global function. -* @function dollar(3) -* @param {string} selector - The selector string. -*/ -dollar = function(a, b) { -}; - -/** -* Describe the instance method. -* @instance -* @function empty -* @memberof dollar(2) -*/ -dollar.prototype.empty = function() { -} - -/** -* Describe the static method. -* @function klass -* @memberof dollar(1) -* @param {string} name -*/ -dollar.klass = function(name) { -}; diff --git a/rsc/scripts/jsdoc/test/fixtures/variations3.js b/rsc/scripts/jsdoc/test/fixtures/variations3.js deleted file mode 100644 index 0b3fdfc4..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/variations3.js +++ /dev/null @@ -1,15 +0,0 @@ -/** -* @constructor -*/ -someObject = function() {} - -/** -* @constructor -* @variation 2 -*/ -someObject = function() {} - -/** -* @memberof someObject(2) -*/ -someMethod = function() {} \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/fixtures/versiontag.js b/rsc/scripts/jsdoc/test/fixtures/versiontag.js deleted file mode 100644 index a482075a..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/versiontag.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - @version 1.2.3 -*/ -function foo(x) { - -} diff --git a/rsc/scripts/jsdoc/test/fixtures/virtual.js b/rsc/scripts/jsdoc/test/fixtures/virtual.js deleted file mode 100644 index 4eb25c1d..00000000 --- a/rsc/scripts/jsdoc/test/fixtures/virtual.js +++ /dev/null @@ -1,3 +0,0 @@ -/** @name dimensions */ - -var width = 12 \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/jasmine-jsdoc.js b/rsc/scripts/jsdoc/test/jasmine-jsdoc.js deleted file mode 100644 index f77b0f5f..00000000 --- a/rsc/scripts/jsdoc/test/jasmine-jsdoc.js +++ /dev/null @@ -1,142 +0,0 @@ -/*global env: true, expect: true, runs: true, waits: true */ -/*jshint evil: true */ -var fs = require('jsdoc/fs'); -var path = require('path'); -var util = require('util'); - -var hasOwnProp = Object.prototype.hasOwnProperty; - -var myGlobal = require('jsdoc/util/global'); - -var jasmineAll = myGlobal.jasmineAll = require('test/lib/jasmine'); -var jasmine = myGlobal.jasmine = jasmineAll.jasmine; - -// due to scoping issues, requiring this file doesn't work -eval( fs.readFileSync(__dirname + '/test/async-callback.js', 'utf8') ); - -var jasmineNode = require('test/reporter').jasmineNode; - -// set up jasmine's global functions -['spyOn', 'it', 'xit', 'expect', 'runs', 'waitsFor', 'beforeEach', 'afterEach', 'describe', - 'xdescribe'].forEach(function(item) { - myGlobal[item] = jasmineAll[item]; -}); - -var reporter = null; -jasmine.initialize = function(done, verbose) { - var jasmineEnv = jasmine.getEnv(); - - if (reporter !== null) { - // If we've run before, we need to reset the runner - jasmineEnv.currentRunner_ = new jasmine.Runner(jasmineEnv); - // And clear the reporter - jasmineEnv.reporter.subReporters_.splice(jasmineEnv.reporter.subReporters_.indexOf(reporter)); - } - - var reporterOpts = { - print: util.print, - color: env.opts.nocolor === true ? false : true, - onComplete: done - }; - - reporter = env.opts.verbose ? new jasmineNode.TerminalVerboseReporter(reporterOpts) : - new jasmineNode.TerminalReporter(reporterOpts); - jasmineEnv.addReporter(reporter); - - // updateInterval is set to 0 because there were not-fully-understood - // issues with asynchronous behavior in jasmine otherwise. - jasmineEnv.updateInterval = 0; - - return jasmineEnv; -}; - -/** - * Execute the specs in the specified folder. Helpers in each folder will be - * added to the environment. Helpers in parent directories will be available to child - * directories. - * @param {string} folder The folder in which the specs are to be found. - * @param {function?} done Callback function to execute when finished. - * @param {object} opts Options for executing the specs. - * @param {boolean} opts.verbose Whether or not to output verbose results. - * @param {RegExp} opts.matcher A regular expression to filter specs by. Only matching specs run. - */ -jasmine.executeSpecsInFolder = function(folder, done, opts) { - var fileMatcher = opts.matcher || new RegExp(".(js)$", "i"), - specs = require('./spec-collection'), - jasmineEnv = jasmine.initialize(done, opts.verbose); - - // Load the specs - specs.load(folder, fileMatcher, true); - - var specsList = specs.getSpecs(); - var filename; - - // Add the specs to the context - for (var i = 0, len = specsList.length; i < len; ++i) { - filename = specsList[i]; - require(filename.path().replace(/\\/g, '/'). - replace(new RegExp('^' + __dirname + '/'), ""). - replace(/\.\w+$/, "")); - } - - // Run Jasmine - jasmineEnv.execute(); -}; - -function now() { - return new Date().getTime(); -} - -jasmine.asyncSpecWait = function() { - var wait = this.asyncSpecWait; - wait.start = now(); - wait.done = false; - (function innerWait() { - waits(10); - runs(function() { - if (wait.start + wait.timeout < now()) { - expect('timeout waiting for spec').toBeNull(); - } else if (wait.done) { - wait.done = false; - } else { - innerWait(); - } - }); - })(); -}; -jasmine.asyncSpecWait.timeout = 4 * 1000; -jasmine.asyncSpecDone = function() { - jasmine.asyncSpecWait.done = true; -}; - -jasmine.getDocSetFromFile = function(filename, parser) { - var sourceCode = fs.readFileSync(__dirname + '/' + filename, 'utf8'), - testParser = parser || new (require('jsdoc/src/parser')).Parser(), - indexAll = require('jsdoc/borrow').indexAll, - doclets; - - require('jsdoc/src/handlers').attachTo(testParser); - - doclets = testParser.parse('javascript:' + sourceCode); - indexAll(doclets); - - require('jsdoc/augment').addInherited(doclets); - - // test assume borrows have not yet been resolved - // require('jsdoc/borrow').resolveBorrows(doclets); - - return { - doclets: doclets, - getByLongname: function(longname) { - return doclets.filter(function(doclet) { - return (doclet.longname || doclet.name) === longname; - }); - } - }; -}; - -for (var key in jasmine) { - if ( hasOwnProp.call(jasmine, key) ) { - exports[key] = jasmine[key]; - } -} diff --git a/rsc/scripts/jsdoc/test/lib/jasmine.js b/rsc/scripts/jsdoc/test/lib/jasmine.js deleted file mode 100644 index 4b4b2b27..00000000 --- a/rsc/scripts/jsdoc/test/lib/jasmine.js +++ /dev/null @@ -1,2547 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS){exports.jasmine = jasmine;} -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0){text += " ";} - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the - * attributes on the object. - * - * @example - * // don't care about any other attributes than foo. - * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); - * - * @param sample {Object} sample - * @returns matchable object for the sample - */ -jasmine.objectContaining = function (sample) { - return new jasmine.Matchers.ObjectContaining(sample); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS){exports.spyOn = spyOn;} - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS){exports.it = it;} - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS){exports.xit = xit;} - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS){exports.expect = expect;} - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS){exports.runs = runs;} - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS){exports.waits = waits;} - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS){exports.waitsFor = waitsFor;} - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS){exports.beforeEach = beforeEach;} - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS){exports.afterEach = afterEach;} - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS){exports.describe = describe;} - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS){exports.xdescribe = xdescribe;} - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) { - throw new Error("This browser does not support XMLHttpRequest."); -} - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) { - return str; -} - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) {arrayOfArgs.push(args[i]);} - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') { - continue; - } - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) { - return result; - } - } - - if (a === b) { - return true; -} - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a.jasmineMatches) { - return a.jasmineMatches(b); - } - - if (b.jasmineMatches) { - return b.jasmineMatches(a); - } - - if (a instanceof jasmine.Matchers.ObjectContaining) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.ObjectContaining) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) { - return true; - } - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') { - continue; - } - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) { - return result; - } - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0){message += ",";} - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.jasmineToString = function() { - return ''; -}; - -jasmine.Matchers.ObjectContaining = function (sample) { - this.sample = sample; -}; - -jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - var env = jasmine.getEnv(); - - var hasKey = function(obj, keyName) { - return obj != null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in this.sample) { - if (!hasKey(other, property) && hasKey(this.sample, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); - } - } - - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { - return ""; -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value.jasmineToString) { - this.emitScalar(value.jasmineToString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') { - continue; - } - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 2, - "build": 0, - "revision": 1333557965, - "release_candidate": 3 -}; diff --git a/rsc/scripts/jsdoc/test/reporter.js b/rsc/scripts/jsdoc/test/reporter.js deleted file mode 100644 index 0678bd8f..00000000 --- a/rsc/scripts/jsdoc/test/reporter.js +++ /dev/null @@ -1,299 +0,0 @@ -(function() { - // - // Imports - // - - if (!jasmineNode) { - var jasmineNode = {}; - } - - // - // Helpers - // - function noop() { - } - - jasmineNode.ANSIColors = { - pass : function() { - return '\033[32m'; - }, // Green - fail : function() { - return '\033[31m'; - }, // Red - neutral : function() { - return '\033[0m'; - } // Normal - }; - - jasmineNode.NoColors = { - pass : function() { - return ''; - }, - fail : function() { - return ''; - }, - neutral : function() { - return ''; - } - }; - - jasmineNode.TerminalReporter = function(config) { - this.print_ = config.print || print; - this.color_ = config.color ? jasmineNode.ANSIColors : jasmineNode.NoColors; - - this.started_ = false; - this.finished_ = false; - - this.callback_ = config.onComplete || false; - - this.suites_ = []; - this.specResults_ = {}; - this.failures_ = {}; - this.failures_.length = 0; - }; - - jasmineNode.TerminalReporter.prototype = { - reportRunnerStarting : function(runner) { - this.started_ = true; - this.startedAt = new Date(); - var suites = runner.topLevelSuites(); - for ( var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } - }, - - summarize_ : function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - - // We could use a separate object for suite and spec - var summary = { - id : suiteOrSpec.id, - name : suiteOrSpec.description, - type : isSuite ? 'suite' : 'spec', - suiteNestingLevel : 0, - children : [] - }; - - if (isSuite) { - var calculateNestingLevel = function(examinedSuite) { - var nestingLevel = 0; - while (examinedSuite.parentSuite !== null) { - nestingLevel += 1; - examinedSuite = examinedSuite.parentSuite; - } - return nestingLevel; - }; - - summary.suiteNestingLevel = calculateNestingLevel(suiteOrSpec); - - var children = suiteOrSpec.children(); - for ( var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - - return summary; - }, - - // This is heavily influenced by Jasmine's Html/Trivial Reporter - reportRunnerResults : function(runner) { - this.reportFailures_(); - - var results = runner.results(); - var resultColor = (results.failedCount > 0) ? this.color_.fail() : this.color_.pass(); - - var specs = runner.specs(); - var specCount = specs.length; - - var message = "\n\nFinished in " - + ((new Date().getTime() - this.startedAt.getTime()) / 1000) - + " seconds"; - this.printLine_(message); - - // This is what jasmine-html.js has - // message = "" + specCount + " spec" + ( specCount === 1 ? "" : "s") + ", " + results.failedCount + " failure" + ((results.failedCount === 1) ? "" : "s"); - - this.printLine_(this.stringWithColor_(this.printRunnerResults_(runner), resultColor)); - - this.finished_ = true; - if (this.callback_) { - this.callback_(runner); - } - }, - - reportFailures_ : function() { - if (this.failures_.length === 0) { - return; - } - - var indent = ' ', failure; - this.printLine_('\n'); - - this.print_('Failures:'); - - for ( var suite in this.failures_) { - if (this.failures_.hasOwnProperty(suite) && suite !== "length") { - this.printLine_('\n'); - this.printLine_(suite); - failures = this.failures_[suite]; - for ( var i = 0; i < failures.length; i++) { - failure = failures[i]; - this.printLine_('\n'); - this.printLine_(indent + (i + 1) + ') ' + failure.spec); - this.printLine_(indent + 'Message:'); - this.printLine_(indent + indent + this.stringWithColor_(failure.message, this.color_.fail())); - this.printLine_(indent + 'Stacktrace:'); - this.print_(indent + indent + failure.stackTrace); - } - } - } - - }, - - reportSuiteResults : function(suite) { - // Not used in this context - }, - - reportSpecResults : function(spec) { - var result = spec.results(); - var msg = ''; - if (result.passed()) { - msg = this.stringWithColor_('.', this.color_.pass()); - // } else if (result.skipped) { TODO: Research why "result.skipped" returns false when "xit" is called on a spec? - // msg = (colors) ? (ansi.yellow + '*' + ansi.none) : '*'; - } else { - msg = this.stringWithColor_('F', this.color_.fail()); - this.addFailureToFailures_(spec); - } - this.spec_results += msg; - this.print_(msg); - }, - - addFailureToFailures_ : function(spec) { - var result = spec.results(); - var failureItem = null; - var suite = spec.suite.getFullName(); - var failures = null; - var items_length = result.items_.length; - for ( var i = 0; i < items_length; i++) { - if (result.items_[i].passed_ === false) { - failureItem = result.items_[i]; - var failure = { - spec : spec.description, - message : failureItem.message, - stackTrace : failureItem.trace.stack - }; - failures = this.failures_[suite]; - if (!failures) { - this.failures_[suite] = []; - } - this.failures_[suite].push(failure); - this.failures_.length++; - } - } - }, - - printRunnerResults_ : function(runner) { - var results = runner.results(); - var specs = runner.specs(); - var msg = ''; - msg += specs.length + ' test' + ((specs.length === 1) ? '' : 's') + ', '; - msg += results.totalCount + ' assertion' + ((results.totalCount === 1) ? '' : 's') + ', '; - msg += results.failedCount + ' failure' + ((results.failedCount === 1) ? '' : 's') + '\n'; - return msg; - }, - - // Helper Methods // - stringWithColor_ : function(stringValue, color) { - return (color || this.color_.neutral()) + stringValue + this.color_.neutral(); - }, - - printLine_ : function(stringValue) { - this.print_(stringValue); - this.print_('\n'); - } - }; - - // *************************************************************** - // TerminalVerboseReporter uses the TerminalReporter's constructor - // *************************************************************** - jasmineNode.TerminalVerboseReporter = function(config) { - jasmineNode.TerminalReporter.call(this, config); - // The extra field in this object - this.indent_ = 0; - }; - - jasmineNode.TerminalVerboseReporter.prototype = { - reportSpecResults : function(spec) { - if (spec.results().failedCount > 0) { - this.addFailureToFailures_(spec); - } - - this.specResults_[spec.id] = { - messages : spec.results().getItems(), - result : spec.results().failedCount > 0 ? 'failed' : 'passed' - }; - }, - - reportRunnerResults : function(runner) { - var messages = new Array(); - this.buildMessagesFromResults_(messages, this.suites_); - - var messages_length = messages.length; - for ( var i = 0; i < messages_length - 1; i++) { - this.printLine_(messages[i]); - } - - this.print_(messages[messages_length - 1]); - - // Call the parent object's method - jasmineNode.TerminalReporter.prototype.reportRunnerResults.call(this, runner); - }, - - buildMessagesFromResults_ : function(messages, results) { - var element, specResult, specIndentSpaces, msg = ''; - - var results_length = results.length; - for ( var i = 0; i < results_length; i++) { - element = results[i]; - - if (element.type === 'spec') { - specResult = this.specResults_[element.id.toString()]; - - specIndentSpaces = this.indent_ + 2; - if (specResult.result === 'passed') { - msg = this.stringWithColor_(this.indentMessage_(element.name, specIndentSpaces), this.color_.pass()); - } else { - msg = this.stringWithColor_(this.indentMessage_(element.name, specIndentSpaces), this.color_.fail()); - } - - messages.push(msg); - } else { - this.indent_ = element.suiteNestingLevel * 2; - - messages.push(''); - messages.push(this.indentMessage_(element.name,this.indent_)); - } - - this.buildMessagesFromResults_(messages, element.children); - } - }, - - indentMessage_ : function(message, indentCount) { - var _indent = ''; - for ( var i = 0; i < indentCount; i++) { - _indent += ' '; - } - return (_indent + message); - } - }; - - // Inherit from TerminalReporter - jasmineNode.TerminalVerboseReporter.prototype.__proto__ = jasmineNode.TerminalReporter.prototype; - - // - // Exports - // - exports.jasmineNode = jasmineNode; -})(); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/runner.js b/rsc/scripts/jsdoc/test/runner.js deleted file mode 100644 index 55f3a96f..00000000 --- a/rsc/scripts/jsdoc/test/runner.js +++ /dev/null @@ -1,57 +0,0 @@ -/*global env: true */ -/* - * Test Steps: - * 1. Get Jasmine - * 2. Get the test options - * 3. Get the list of directories to run tests from - * 4. Run Jasmine on each directory - */ -var fs = require('jsdoc/fs'); -var jasmine = require('test/jasmine-jsdoc'); -var path = require('path'); - -fs.existsSync = fs.existsSync || path.existsSync; - -var hasOwnProp = Object.prototype.hasOwnProperty; - -for (var key in jasmine) { - if (hasOwnProp.call(jasmine, key)) { - this[key] = jasmine[key]; - } -} - -var opts = { - verbose: env.opts.verbose || false, - showColors: env.opts.nocolor === true ? false : true -}; - -var extensions = 'js'; -var match = env.opts.match || '.'; -if (match instanceof Array) { - match = match.join("|"); -} -opts.matcher = new RegExp("(" + match + ")\\.(" + extensions + ")$", 'i'); - -var specFolders = ['test/specs', 'plugins/test/specs']; - -var failedCount = 0; -var index = 0; - -var onComplete; - -function runNextFolder() { - if (index < specFolders.length) { - jasmine.executeSpecsInFolder(specFolders[index], onComplete, opts); - } -} - -onComplete = function(runner, log) { - if (runner.results().failedCount !== 0) { - failedCount += runner.results().failedCount; - } - index++; - runNextFolder(); -}; - -runNextFolder(); -process.exit(failedCount); diff --git a/rsc/scripts/jsdoc/test/spec-collection.js b/rsc/scripts/jsdoc/test/spec-collection.js deleted file mode 100644 index 24e23a06..00000000 --- a/rsc/scripts/jsdoc/test/spec-collection.js +++ /dev/null @@ -1,55 +0,0 @@ -/*global env: true */ -var wrench = require('wrench'); -var path = require('path'); -var fs = require('jsdoc/fs'); -var specs = []; - -var createSpecObj = function(_path, root) { - function relativePath() { - return _path.replace(root, '').replace(/^[\/\\]/, '').replace(/\\/g, '/'); - } - - return { - path: function() { - return _path; - }, - relativePath: relativePath, - directory: function() { - return _path.replace(/[\/\\][\s\w\.\-]*$/, "").replace(/\\/g, '/'); - }, - relativeDirectory: function() { - return relativePath().replace(/[\/\\][\s\w\.\-]*$/, "").replace(/\\/g, '/'); - }, - filename: function() { - return _path.replace(/^.*[\\\/]/, ''); - } - }; -}; - -var clearSpecs = exports.clearSpecs = function() { - specs.splice(0, specs.length); -}; - -exports.load = function(loadpath, matcher, clear) { - if (clear === true) { - clearSpecs(); - } - - var wannaBeSpecs = wrench.readdirSyncRecursive(loadpath); - for (var i = 0; i < wannaBeSpecs.length; i++) { - var file = path.join(__dirname, loadpath, wannaBeSpecs[i]); - try { - if (fs.statSync(file).isFile()) { - if (matcher.test(path.basename(file))) { - specs.push(createSpecObj(file)); - } - } - } catch(e) { - // nothing to do here - } - } -}; - -exports.getSpecs = function() { - return specs; -}; diff --git a/rsc/scripts/jsdoc/test/specs/documentation/alias.js b/rsc/scripts/jsdoc/test/specs/documentation/alias.js deleted file mode 100644 index 23508e1d..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/alias.js +++ /dev/null @@ -1,67 +0,0 @@ -describe("aliases", function() { - describe("standard", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/alias.js'), - found = docSet.getByLongname('myObject').filter(function($) { - return ! $.undocumented; - }), - foundMember = docSet.getByLongname('myObject.myProperty'); - - it('When a symbol is given an alias it is documented as if the name is the alias value.', function() { - expect(found[0].longname).toEqual('myObject'); - }); - - it('When a symbol is a member of an alias it is documented as if the memberof is the alias value.', function() { - expect(foundMember[0].longname).toEqual('myObject.myProperty'); - expect(foundMember[0].memberof).toEqual('myObject'); - }); - }); - - it('When a symbol is a member of an alias of a nested name it is documented as if the memberof is the nested alias value.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/alias2.js'), - foundMember = docSet.getByLongname('ns.Myclass#myProperty'); - - expect(foundMember[0].longname).toEqual('ns.Myclass#myProperty'); - expect(foundMember[0].name).toEqual('myProperty'); - expect(foundMember[0].memberof).toEqual('ns.Myclass'); - expect(foundMember[0].scope).toEqual('instance'); - }); - - it('When a symbol is a member of an aliased class, a this-variables is documented as if it were a member that class.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/alias3.js'), - tcm = docSet.getByLongname('trackr.CookieManager')[0], - tcmValue = docSet.getByLongname('trackr.CookieManager#value')[0]; - - expect(tcmValue.memberof).toEqual('trackr.CookieManager'); - }); - - it('When a symbol is documented as a static member of it\'s scope is "global" and not "static".', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/aliasglobal.js'), - log = docSet.getByLongname('log')[0]; - - expect(log.scope).toEqual('global'); - }); - - it('When a symbol is documented as an instance member of class it\'s scope is "instance" and not "static".', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/aliasglobal2.js'), - run = docSet.getByLongname('Test#run')[0]; - - expect(run.scope).toEqual('instance'); - expect(run.memberof).toEqual('Test'); - }); - - describe("resolving", function() { - it('When a local reference has alias, put all members into aliased definition. Local modifications should be visible to outside.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/aliasresolve.js'), - method = docSet.getByLongname('A.F.method'); - - expect(method.length).toEqual(1); - }); - - it('When a reference in an outer scope has alias, put all members into aliased definition. Local modifications are visible to outside.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/aliasresolve2.js'), - method = docSet.getByLongname('A.F.method'); - - expect(method.length).toEqual(1); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/also.js b/rsc/scripts/jsdoc/test/specs/documentation/also.js deleted file mode 100644 index ca71151a..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/also.js +++ /dev/null @@ -1,47 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("multiple doclets per symbol", function() { - function undocumented($) { - return ! $.undocumented; - } - - function checkInequality(doclets, property) { - for (var l = doclets.length - 1; l > 0; l--) { - if (doclets[l][property] !== undefined && doclets[l - 1][property] !== undefined) { - expect(doclets[l][property]).not.toBe(doclets[l - 1][property]); - } - } - } - - var docSet = jasmine.getDocSetFromFile('test/fixtures/also.js'); - var name = docSet.getByLongname('Asset#name').filter(undocumented); - var shape = docSet.getByLongname('Asset#shape').filter(undocumented); - - it('When a symbol has multiple adjacent JSDoc comments, both apply to the symbol.', function() { - expect(name.length).toBe(2); - expect(shape.length).toBe(3); - }); - - it('When a symbol has multiple adjacent JSDoc comments that are not identical, the doclets ' + - 'have different comments.', function() { - checkInequality(name, 'comment'); - checkInequality(shape, 'comment'); - }); - - it('When a symbol has multiple adjacent JSDoc comments with different descriptions, ' + - 'the doclets have different descriptions.', function() { - checkInequality(name, 'description'); - checkInequality(shape, 'description'); - }); - - it('When a symbol has multiple adjacent JSDoc comments with different numbers of ' + - '@param tags, the doclets have different parameter lists.', function() { - checkInequality(name, 'params.length'); - checkInequality(shape, 'params.length'); - }); - - it('When a symbol has multiple adjacent JSDoc comments with different numbers of ' + - '@returns tags, the doclets have different lists of return values.', function() { - checkInequality(name, 'returns.length'); - checkInequality(shape, 'returns.length'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/documentation/callback.js b/rsc/scripts/jsdoc/test/specs/documentation/callback.js deleted file mode 100644 index d8e14412..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/callback.js +++ /dev/null @@ -1,27 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe('callback tag', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/callbacktag.js'); - - function callbackTests(callback) { - expect(callback).toBeDefined(); - - expect(callback.type).toBeDefined(); - expect(typeof callback.type).toEqual('object'); - - expect(callback.type.names).toBeDefined(); - expect(callback.type.names instanceof Array).toEqual(true); - expect(callback.type.names.length).toEqual(1); - - expect(callback.type.names[0]).toEqual('function'); - } - - it('correctly handles callbacks that do not define a {type}', function() { - var callback = docSet.getByLongname('requestResponseCallback')[0]; - callbackTests(callback); - }); - - it('correctly handles callbacks that define an incorrect {type}', function() { - var callback = docSet.getByLongname('wrongTypeCallback')[0]; - callbackTests(callback); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/documentation/exports.js b/rsc/scripts/jsdoc/test/specs/documentation/exports.js deleted file mode 100644 index 39e7debc..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/exports.js +++ /dev/null @@ -1,11 +0,0 @@ -describe("'exports' symbol in modules", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exports.js'), - helloworld = docSet.getByLongname('module:hello/world')[0], - sayhello = docSet.getByLongname('module:hello/world.sayHello')[0]; - - it('When a symbol starts with the special name "exports" and is in a file with a @module tag, the symbol is documented as a member of that module.', function() { - expect(typeof sayhello).toEqual('object'); - expect(sayhello.kind).toEqual('function'); - expect(sayhello.memberof).toEqual('module:hello/world'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/getset.js b/rsc/scripts/jsdoc/test/specs/documentation/getset.js deleted file mode 100644 index d88ebe6f..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/getset.js +++ /dev/null @@ -1,23 +0,0 @@ -describe("When a getter or setter is the child of an object literal", function () { - var docSet = jasmine.getDocSetFromFile("test/fixtures/getset.js"), - foundName = docSet.getByLongname("Person#name"), - foundAge = docSet.getByLongname("Person#age"); - - it("should have a doclet with the correct longname", function () { - expect(foundName.length).toEqual(2); - expect(foundAge.length).toEqual(1); - }); - - it("should have a doclet with the correct name", function () { - expect(foundName[0].name).toEqual("name"); - expect(foundName[1].name).toEqual("name"); - expect(foundAge[0].name).toEqual("age"); - }); - - it("should have the correct memberof", function () { - expect(foundName[0].memberof).toEqual("Person"); - expect(foundName[1].memberof).toEqual("Person"); - expect(foundAge[0].memberof).toEqual("Person"); - }); - -}); diff --git a/rsc/scripts/jsdoc/test/specs/documentation/inlinecomment.js b/rsc/scripts/jsdoc/test/specs/documentation/inlinecomment.js deleted file mode 100644 index d2692ec1..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/inlinecomment.js +++ /dev/null @@ -1,12 +0,0 @@ -describe("inline comments", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/inlinecomment.js'), - t = docSet.getByLongname('test'), - t2 = docSet.getByLongname('test2'); - - it('When there is an inline comment on a line ending with no semicolon, that comment and the next comment are still captured', function() { - //Inline comment on line without semicolon is captured - expect(t.length).toEqual(1); - //Inline comment on line after line without semicolon is captured - expect(t2.length).toEqual(1); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/inner.js b/rsc/scripts/jsdoc/test/specs/documentation/inner.js deleted file mode 100644 index d69594ea..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/inner.js +++ /dev/null @@ -1,24 +0,0 @@ -describe("when a documented var memeber is inside a named function", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/inner.js'), - found1 = docSet.getByLongname('sendMessage~encoding'), - found2 = docSet.getByLongname('sendMessage~encrypt'); - - it("A Doclet with the correct longname should be found", function() { - expect(found1.length).toEqual(1); - expect(found2.length).toEqual(1); - }); - - it("The short name should be correct", function() { - expect(found1[0].name).toEqual('encoding'); - expect(found2[0].name).toEqual('encrypt'); - }); - - it("The member of should be correct", function() { - expect(found1[0].memberof).toEqual('sendMessage'); - expect(found2[0].memberof).toEqual('sendMessage'); - }); - it("The scope should default to 'inner'", function() { - expect(found1[0].scope).toEqual('inner'); - expect(found2[0].scope).toEqual('inner'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/innerscope.js b/rsc/scripts/jsdoc/test/specs/documentation/innerscope.js deleted file mode 100644 index 01cad5fc..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/innerscope.js +++ /dev/null @@ -1,40 +0,0 @@ -describe("inner scope", function() { - describe("Outer~inner.member cases", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/innerscope.js'), - to = docSet.getByLongname('Message~headers.to'), - from = docSet.getByLongname('Message~headers.from'), - response = docSet.getByLongname('Message~response.code'); - - it('should occur when a member of a var member is documented.', function() { - expect(to.length).toEqual(1); - }); - - it('should occur when a second member of a var member is documented.', function() { - expect(response.length).toEqual(1); - }); - - it('should occur when a deeply nested member of a var member is documented.', function() { - expect(from.length).toEqual(1); - }); - }); - - describe("other cases", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/innerscope2.js'), - to = docSet.getByLongname('Message~headers.to'), - from = docSet.getByLongname('~headers.from'), - cache = docSet.getByLongname('~headers.cache'); - - it('When a var is declared in a function, It is like Inner~member', function() { - expect(cache.length).toEqual(1); - }); - - it('When a var is masked by an inner var and a member of the inner is documented, it is like Inner~inner.member', function() { - expect(from.length).toEqual(1); - }); - - it('When a documented member is assigned to a var that masks an outer var.', function() { - expect(from[0].name).toEqual('from'); - expect(from[0].memberof).toEqual('~headers'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/lends.js b/rsc/scripts/jsdoc/test/specs/documentation/lends.js deleted file mode 100644 index fe24a13c..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/lends.js +++ /dev/null @@ -1,71 +0,0 @@ -describe("lends", function() { - describe("when a documented member is inside an object literal associate with a @lends tag", function() { - describe("standard case", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/lends.js'), - init = docSet.getByLongname('Person#initialize'), - name = docSet.getByLongname('Person#name'); - - it("The member should be documented as a member of the lendee", function() { - expect(init.length, 1); - }); - - it("The this member should be documented as a member of the lendee", function() { - expect(name.length, 1); - }); - }); - - describe("case containg constructor", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/lends2.js'), - person = docSet.getByLongname('Person').filter(function($) { - return ! $.undocumented; - })[0], - name = docSet.getByLongname('Person#name'); - - it("A tag with a @constructs tag is documented as a constructor.", function() { - expect(person.description).toEqual('Construct a Person.'); - }); - - it("The member should be documented as a member of the lendee", function() { - expect(person.length, 1); - }); - - it("The this member should be documented as a member of the lendee", function() { - expect(name.length, 1); - }); - }); - - describe("case that uses @lends in a multiline doclet", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/lends3.js'), - init = docSet.getByLongname('Person#initialize'), - name = docSet.getByLongname('Person#name'); - - it("The member should be documented as a member of the lendee", function() { - expect(init.length, 1); - }); - - it("The this member should be documented as a member of the lendee", function() { - expect(name.length, 1); - }); - }); - - }); - - describe("when a documented member is inside an objlit associated with a @lends tag that has no value.", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/lendsglobal.js'), - testf = docSet.getByLongname('test')[0], - test1 = docSet.getByLongname('test1')[0], - test12 = docSet.getByLongname('test1.test2')[0]; - - it("The members of the objlit are not members of any symbol", function() { - expect(typeof testf.memberof).toEqual('undefined'); - }); - - it("The members of the objlit are documented as global.", function() { - expect(testf.longname).toEqual('test'); - }); - - it("The nested members of the objlit are members of a global symbol", function() { - expect(test12.memberof).toEqual('test1'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/moduleinner.js b/rsc/scripts/jsdoc/test/specs/documentation/moduleinner.js deleted file mode 100644 index 1a783c96..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/moduleinner.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("inner scope for modules", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/moduleinner.js'), - fooIn = docSet.getByLongname('module:my/module~fooIn')[0], - fooOut = docSet.getByLongname('module:my/module~fooOut')[0]; - - it('When a function appears in the topscope of a module, the symbol is documented as an inner member of that module.', function() { - expect(typeof fooOut).toEqual('object'); - expect(fooOut.longname).toEqual('module:my/module~fooOut'); - - expect(typeof fooIn).toEqual('object'); - expect(fooIn.longname).toEqual('module:my/module~fooIn'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/moduleisconstructor.js b/rsc/scripts/jsdoc/test/specs/documentation/moduleisconstructor.js deleted file mode 100644 index 6b0cbe61..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/moduleisconstructor.js +++ /dev/null @@ -1,5 +0,0 @@ -/*global describe: true, expect: true, it: true, xdescribe: true */ - -xdescribe('module that exports a constructor', function() { - // TODO -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/moduleisfunction.js b/rsc/scripts/jsdoc/test/specs/documentation/moduleisfunction.js deleted file mode 100644 index 1aeb783d..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/moduleisfunction.js +++ /dev/null @@ -1,23 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ - -describe('module that exports a function that is not a constructor', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/moduleisfunction.js'); - var functions = docSet.doclets.filter(function(doclet) { - return doclet.kind === 'function'; - }); - - it('should include one doclet whose kind is "function"', function() { - expect(functions.length).toBe(1); - expect(functions[0].kind).toBe('function'); - }); - - describe('function doclet', function() { - it('should not include a "scope" property', function() { - expect(functions[0].scope).not.toBeDefined(); - }); - - it('should not include a "memberof" property', function() { - expect(functions[0].memberof).not.toBeDefined(); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/documentation/modules.js b/rsc/scripts/jsdoc/test/specs/documentation/modules.js deleted file mode 100644 index 52481150..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/modules.js +++ /dev/null @@ -1,23 +0,0 @@ -/*global beforeEach: true, describe: true, env: true, expect: true, it: true */ -describe("module names", function() { - var parser = require('jsdoc/src/parser'), - srcParser = null, doclets; - - beforeEach(function() { - env.opts._ = [__dirname + '/test/fixtures/modules/']; - srcParser = new parser.Parser(); - require('jsdoc/src/handlers').attachTo(srcParser); - }); - - it("should create a name from the file path when no documented module name exists", function() { - doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-1.js'); - expect(doclets.length).toBeGreaterThan(1); - expect(doclets[0].longname).toEqual('module:data/mod-1'); - }); - - it("should use the documented module name if available", function() { - doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-2.js'); - expect(doclets.length).toBeGreaterThan(1); - expect(doclets[0].longname).toEqual('module:my/module/name'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/namedFuncStatement.js b/rsc/scripts/jsdoc/test/specs/documentation/namedFuncStatement.js deleted file mode 100644 index 5dd1de6f..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/namedFuncStatement.js +++ /dev/null @@ -1,43 +0,0 @@ -describe("named function statements", function() { - describe("standard", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/namedFuncStatement.js'), - fooMember = docSet.getByLongname('Foo#member1')[0], - fooVariable = docSet.getByLongname('Foo~var1')[0]; - - it('A symbol that is a member of a named function statement should documented as a member of the assigned name', function() { - expect(fooMember.longname).toEqual('Foo#member1'); - }); - - it('A symbol that is a variable of a named function statement should documented as a member of the assigned name', function() { - expect(fooVariable.longname).toEqual('Foo~var1'); - }); - }); - - describe("global", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/namedFuncStatement2.js'), - fooMember = docSet.getByLongname('Foo#member1')[0], - fooVariable = docSet.getByLongname('Foo~var1')[0]; - - it('A symbol that is a member of a named function statement should documented as a member of the assigned name', function() { - expect(fooMember.longname).toEqual('Foo#member1'); - }); - - it('A symbol that is a variable of a named function statement should documented as a member of the assigned name', function() { - expect(fooVariable.longname).toEqual('Foo~var1'); - }); - }); - - describe("as object literal property", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/namedFuncStatement3.js'), - fooMember = docSet.getByLongname('ns.Foo#member1')[0], - fooVariable = docSet.getByLongname('ns.Foo~var1')[0]; - - it('A symbol that is a member of a named function statement should documented as a member of the assigned name', function() { - expect(fooMember.longname).toEqual('ns.Foo#member1'); - }); - - it('A symbol that is a variable of a named function statement should documented as a member of the assigned name', function() { - expect(fooVariable.longname).toEqual('ns.Foo~var1'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/objectlit.js b/rsc/scripts/jsdoc/test/specs/documentation/objectlit.js deleted file mode 100644 index 1bc09d0b..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/objectlit.js +++ /dev/null @@ -1,43 +0,0 @@ -describe("object literals", function() { - describe("When a child of an objlit has no @name or @memberof tags", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/objectlit.js'), - found = docSet.getByLongname('tools.serialiser.value'); - - it("should have a doclet with the correct longname", function() { - expect(found.length).toEqual(1); - }); - - it("should have a doclet with the correct name", function() { - expect(found[0].name).toEqual('value'); - }); - - it("should have the correct memberof", function() { - expect(found[0].memberof).toEqual('tools.serialiser'); - }); - - it("should have a static scope", function() { - expect(found[0].scope).toEqual('static'); - }); - }); - - describe("When a parent of an objlit has no documentation", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/objectlit2.js'), - found = docSet.getByLongname('position.axis.x'); - - it("should have a doclet with the correct longname", function() { - expect(found.length).toEqual(1); - }); - - it("should have a doclet with the correct name", function() { - expect(found[0].name).toEqual('x'); - }); - - it("should have the correct memberof", function() { - expect(found[0].memberof).toEqual('position.axis'); - }); - - it("should have a static scope", function() { - expect(found[0].scope).toEqual('static'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/objectpropertykeys.js b/rsc/scripts/jsdoc/test/specs/documentation/objectpropertykeys.js deleted file mode 100644 index 0cb39e22..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/objectpropertykeys.js +++ /dev/null @@ -1,6 +0,0 @@ -describe("using existing Object properties as object literal keys", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/objectpropertykeys.js'); - it("should not crash", function() { - expect(true).toBeTruthy(); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/quotename.js b/rsc/scripts/jsdoc/test/specs/documentation/quotename.js deleted file mode 100644 index 41d30902..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/quotename.js +++ /dev/null @@ -1,23 +0,0 @@ -describe("quoted names", function() { - - describe("when found in square brackets", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/quotename.js'), - found1 = docSet.getByLongname('chat.\"#channel\".open')[0]; - - - it('should have correct name and memberof', function() { - expect(found1.name).toEqual('open'); - expect(found1.memberof).toEqual('chat.\"#channel\"'); - }); - }); - - describe("when found in an object literal", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/quotename2.js'), - found1 = docSet.getByLongname("contacts.\"say-\\\"hello\\\"@example.com\".username")[0]; - - it('should have correct name and memberof', function() { - expect(found1.name).toEqual('username'); - expect(found1.memberof).toEqual("contacts.\"say-\\\"hello\\\"@example.com\""); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/specialnames.js b/rsc/scripts/jsdoc/test/specs/documentation/specialnames.js deleted file mode 100644 index f6d8b62b..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/specialnames.js +++ /dev/null @@ -1,10 +0,0 @@ -describe("documenting symbols with special names", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/specialnames.js'), - name = docSet.getByLongname('hasOwnProperty').filter(function($) { - return ! $.undocumented; - }); - - it('When a symbol has the documented name of "hasOwnProperty," JSDoc should correctly include it in the docs.', function() { - expect(name.length).toEqual(1); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/starbangstar.js b/rsc/scripts/jsdoc/test/specs/documentation/starbangstar.js deleted file mode 100644 index 0a875bb4..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/starbangstar.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("starbangstar", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/starbangstar.js'), - mod = docSet.getByLongname('module:myscript/core')[0], - x = docSet.getByLongname('module:myscript/core.x')[0]; - - it('should not treat a doclet starting with /*!* as a JSDoc comment.', function() { - expect(mod.description).toEqual('Script that does something awesome'); - }); - - it('should not treat a doclet starting with /*!** as a JSDoc comment.', function() { - expect(x).toBeUndefined(); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/this.js b/rsc/scripts/jsdoc/test/specs/documentation/this.js deleted file mode 100644 index 6393dba4..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/this.js +++ /dev/null @@ -1,102 +0,0 @@ -describe("this", function() { - describe("attaching members to 'this'", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/this.js'), - found1 = docSet.getByLongname('Singer#tralala'), - found2 = docSet.getByLongname('Singer#isSinging'); - - describe("in a contructor", function() { - it("should have a longname like Constructor#member", function() { - expect(found1.length).toEqual(1); - }); - - it("should havea correct short name", function() { - expect(found1[0].name).toEqual('tralala'); - }); - - it("should havea correct memberof", function() { - expect(found1[0].memberof).toEqual('Singer'); - }); - - it("should default to a 'instance' scope", function() { - expect(found1[0].scope).toEqual('instance'); - }); - }); - - describe("in a method of a constructor", function() { - it("should have a longname like Constructor#member", function() { - expect(found2.length).toEqual(1); - }); - - it("should havea correct short name", function() { - expect(found2[0].name).toEqual('isSinging'); - }); - - it("should havea correct memberof", function() { - expect(found2[0].memberof).toEqual('Singer'); - }); - - it("should default to a 'instance' scope", function() { - expect(found2[0].scope).toEqual('instance'); - }); - }); - }); - - describe("when a contructor is nested inside another constructor", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/this2.js'), - found = docSet.getByLongname('TemplateBuilder#Template#rendered'); - - it("should have a longname like Constructor#Constructor#member", function() { - expect(found.length).toEqual(1); - }); - - it("should havea correct short name", function() { - expect(found[0].name).toEqual('rendered'); - }); - - it("should havea correct memberof", function() { - expect(found[0].memberof).toEqual('TemplateBuilder#Template'); - }); - - it("should default to a 'instance' scope", function() { - expect(found[0].scope).toEqual('instance'); - }); - }); - - describe("When a this is assigned to inside a non-constructor function", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/this3.js'), - found = docSet.getByLongname('position'); - - it("should have a global member name like 'member'", function() { - expect(found.length).toEqual(1); - }); - - it("should havea correct short name", function() { - expect(found[0].name).toEqual('position'); - }); - - it("should havea correct memberof", function() { - expect(found[0].memberof).toBeUndefined(); - }); - }); - - describe("When a member is nested inside an objectlit 'this' property inside a constructor", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/this-and-objectlit.js'), - found = docSet.getByLongname('Page#parts.body.heading'); - - it("should have a longname like Constructor#objlit.member", function() { - expect(found.length).toEqual(1); - }); - - it("should havea correct short name", function() { - expect(found[0].name).toEqual('heading'); - }); - - it("should havea correct memberof", function() { - expect(found[0].memberof).toEqual('Page#parts.body'); - }); - - it("should default to a 'static' scope", function() { - expect(found[0].scope).toEqual('static'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/var.js b/rsc/scripts/jsdoc/test/specs/documentation/var.js deleted file mode 100644 index a9b85fe5..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/var.js +++ /dev/null @@ -1,58 +0,0 @@ -describe("var statements", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/var.js'), - found = [ - docSet.getByLongname('GREEN'), - docSet.getByLongname('RED'), - docSet.getByLongname('validate'), - docSet.getByLongname('i'), - docSet.getByLongname('results') - ]; - - describe("when a series of constants are documented", function() { - it("should find the first constant", function() { - expect(found[0].length).toEqual(1); - }); - - it("attach the docs to the first constant", function() { - expect(found[0][0].comment).toEqual('/** document me */'); - }); - - it("should have a correct short name", function() { - expect(found[0][0].name).toEqual('GREEN'); - }); - - it("should have a correct memberof", function() { - expect(found[0][0].memberof).toBeUndefined(); - }); - - it("should give the constant a global scope", function() { - expect(found[0][0].scope).toEqual('global'); - }); - - it("should find the second constant", function() { - expect(found[1].length).toEqual(1); - }); - - it("should not attach the docs to the second constant", function() { - expect(found[1][0].undocumented).toEqual(true); - }); - }); - - describe('When a member of a series of vars are documented.', function() { - it("should attach the docs to the correct var", function() { - expect(found[4][0].comment).toEqual('/** document me */'); - }); - - it("should hav a correct short name", function() { - expect(found[4][0].name).toEqual('results'); - }); - - it("should leave memberof undefined", function() { - expect(found[4][0].memberof).toBeUndefined(); - }); - - it("should give the var a global scope", function() { - expect(found[4][0].scope).toEqual('global'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/variations.js b/rsc/scripts/jsdoc/test/specs/documentation/variations.js deleted file mode 100644 index 3bf133c8..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/variations.js +++ /dev/null @@ -1,38 +0,0 @@ -describe("variations", function() { - - describe("by name", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/variations.js'), - fadein1 = docSet.getByLongname('anim.fadein(1)')[0], - fadein2 = docSet.getByLongname('anim.fadein(2)')[0]; - - it('When a symbol has a name with a variation, the doclet has a variation property.', function() { - expect(fadein1.variation).toEqual('1'); - expect(fadein2.variation).toEqual('2'); - }); - - it('When a symbol has a name with a variation in the name, the doclet name has no variation in it.', function() { - expect(fadein1.name).toEqual('fadein'); - expect(fadein2.name).toEqual('fadein'); - }); - - it('When a symbol has a name with a variation in the name, the doclet longname has the variation in it.', function() { - expect(fadein1.longname).toEqual('anim.fadein(1)'); - expect(fadein2.longname).toEqual('anim.fadein(2)'); - }); - }); - - describe("by tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/variations3.js'), - someObject = docSet.getByLongname('someObject')[0], - someObject2 = docSet.getByLongname('someObject(2)')[0], - someObject2method = docSet.getByLongname('someObject(2).someMethod')[0]; - - it('When a symbol has a variation tag, the longname includes that variation.', function() { - expect(someObject2.longname).toEqual('someObject(2)'); - }); - - it('When a symbol is a member of a variation, the longname includes the variation.', function() { - expect(someObject2method.longname).toEqual('someObject(2).someMethod'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/documentation/virtual.js b/rsc/scripts/jsdoc/test/specs/documentation/virtual.js deleted file mode 100644 index b6c89db6..00000000 --- a/rsc/scripts/jsdoc/test/specs/documentation/virtual.js +++ /dev/null @@ -1,15 +0,0 @@ -describe("virtual symbols", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/virtual.js'), - found = [ - docSet.getByLongname('dimensions'), - docSet.getByLongname('width') - ]; - - it('should document virtual symbols', function() { - expect(found[0].length).toEqual(1); - }); - - it('should document an undocumented symbol found after a comment for a virtual symbol', function() { - expect(found[1].length).toEqual(1); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/augment.js b/rsc/scripts/jsdoc/test/specs/jsdoc/augment.js deleted file mode 100644 index 7b2daf92..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/augment.js +++ /dev/null @@ -1,4 +0,0 @@ -/*global describe: true, env: true, it: true */ -describe("jsdoc/augment", function() { - // TODO -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/borrow.js b/rsc/scripts/jsdoc/test/specs/jsdoc/borrow.js deleted file mode 100644 index 4085d9b1..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/borrow.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("jsdoc/borrow", function() { - //TODO -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/config.js b/rsc/scripts/jsdoc/test/specs/jsdoc/config.js deleted file mode 100644 index 24e024fe..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/config.js +++ /dev/null @@ -1,47 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("jsdoc/config", function() { - var jsdoc = {config: require('jsdoc/config') }; - - it("should exist", function() { - expect(jsdoc.config).toBeDefined(); - expect(typeof jsdoc.config).toEqual("function"); - }); - - it("should provide a 'get' instance function", function() { - var config = new jsdoc.config(); - expect(config.get).toBeDefined(); - expect(typeof config.get).toEqual("function"); - }); - - describe ("constructor with empty", function() { - it('should be possible to construct a Config with an empty arguments', function() { - var config = new jsdoc.config().get(); - - expect(config.plugins).toEqual([]); - }); - }); - - describe ("constructor with {}", function() { - it('should be possible to construct a Config with JSON of an object literal that is emptys', function() { - var config = new jsdoc.config('{}').get(); - - expect(config.plugins).toEqual([]); - }); - }); - - describe ("constructor with plugins value", function() { - it('should be possible to construct a Config with JSON of an object literal that has a plugin value', function() { - var config = new jsdoc.config('{"plugins":[42]}').get(); - - expect(config.plugins).toEqual([42]); - }); - }); - - describe ("constructor with source value", function() { - it('should be possible to construct a Config with JSON of an object literal that has a source value', function() { - var config = new jsdoc.config('{"source":{"includePattern":"hello"}}').get(); - - expect(config.source.includePattern).toEqual('hello'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/doclet.js b/rsc/scripts/jsdoc/test/specs/jsdoc/doclet.js deleted file mode 100644 index efeaed25..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/doclet.js +++ /dev/null @@ -1,16 +0,0 @@ -/*global describe: true, env: true, expect: true, it: true, jasmine: true */ -describe("jsdoc/doclet", function() { - // TODO: more tests - - var docSet = jasmine.getDocSetFromFile('test/fixtures/doclet.js'), - test1 = docSet.getByLongname('test1')[0], - test2 = docSet.getByLongname('test2')[0]; - - var expectStrong = "**Strong** is strong"; - var expectList = "* List item 1"; - - it('does not mangle Markdown in a description that uses leading asterisks', function() { - expect(test2.description.indexOf(expectStrong)).toBeGreaterThan(-1); - expect(test2.description.indexOf(expectList)).toBeGreaterThan(-1); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/name.js b/rsc/scripts/jsdoc/test/specs/jsdoc/name.js deleted file mode 100644 index f8ba382b..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/name.js +++ /dev/null @@ -1,285 +0,0 @@ -/*global describe: true, expect: true, it: true */ - -describe("jsdoc/name", function() { - var jsdoc = {name: require('jsdoc/name'), doclet: require('jsdoc/doclet') }; - - it("should exist", function() { - expect(jsdoc.name).toBeDefined(); - expect(typeof jsdoc.name).toEqual("object"); - }); - - it("should export an 'resolve' function", function() { - expect(jsdoc.name.resolve).toBeDefined(); - expect(typeof jsdoc.name.resolve).toEqual("function"); - }); - - it("should export an 'applyNamespace' function", function() { - expect(jsdoc.name.applyNamespace).toBeDefined(); - expect(typeof jsdoc.name.applyNamespace).toEqual("function"); - }); - - it("should export an 'shorten' function", function() { - expect(jsdoc.name.shorten).toBeDefined(); - expect(typeof jsdoc.name.shorten).toEqual("function"); - }); - - it("should export an 'splitName' function", function() { - expect(jsdoc.name.splitName).toBeDefined(); - expect(typeof jsdoc.name.splitName).toEqual("function"); - }); - - describe ("shorten", function() { - it('should break up a longname into the correct memberof, name and scope parts', function() { - var startName = 'lib.Panel#open', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('open'); - expect(parts.memberof).toEqual('lib.Panel'); - expect(parts.scope).toEqual('#'); - }); - - it('should work on static names', function() { - var startName = 'elements.selected.getVisible', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('getVisible'); - expect(parts.memberof).toEqual('elements.selected'); - expect(parts.scope).toEqual('.'); - }); - - it('should work on protoyped names', function() { - var startName = 'Validator.prototype.$element', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('$element'); - expect(parts.memberof).toEqual('Validator'); - expect(parts.scope).toEqual('#'); - }); - - it('should work on inner names.', function() { - var startName = 'Button~_onclick', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('_onclick'); - expect(parts.memberof).toEqual('Button'); - expect(parts.scope).toEqual('~'); - }); - - it('should work on global names.', function() { - var startName = 'close', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('close'); - //'The memberof should be an empty string for global symbols.' - expect(parts.memberof).toEqual(''); - //'The scope should be an empty string for global symbols.' - expect(parts.scope).toEqual(''); - }); - - it('should work on bracketed stringy names', function() { - var startName = 'channels["#ops"]#open', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('open'); - //'Bracketed stringy names should appear as quoted strings.' - expect(parts.memberof).toEqual('channels."#ops"'); - expect(parts.scope).toEqual('#'); - - startName = 'channels["#bots"]["log.max"]', - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toEqual('"log.max"'); - expect(parts.memberof).toEqual('channels."#bots"'); - expect(parts.scope).toEqual('.'); - }); - - it('should work on bracketed stringy names with single quotes', function() { - var startName = "channels['#ops']", - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toBe("'#ops'"); - expect(parts.memberof).toBe('channels'); - expect(parts.scope).toBe('.'); - }); - - it('should work on fully stringy names, like "foo.bar"', function() { - var startName = '"foo.bar"', - parts = jsdoc.name.shorten(startName); - - //'The name should be the full quoted string.' - expect(parts.name).toEqual('"foo.bar"'); - //'The longname should be the full quoted string.' - expect(parts.longname).toEqual('"foo.bar"'); - //'There should be no memberof, as it is global.' - expect(parts.memberof).toEqual(''); - //'The scope should be as global.' - expect(parts.scope).toEqual(''); - }); - - it('should work on fully stringy names in single quotes, like \'foo.bar\'', function() { - var startName = "'foo.bar'", - parts = jsdoc.name.shorten(startName); - - expect(parts.name).toBe("'foo.bar'"); - expect(parts.longname).toBe("'foo.bar'"); - expect(parts.memberof).toBe(''); - expect(parts.scope).toBe(''); - }); - - it('should find the variation', function() { - var startName = 'anim.fadein(2)', - parts = jsdoc.name.shorten(startName); - - expect(parts.variation).toEqual('2'); - expect(parts.name).toEqual('fadein'); - expect(parts.longname).toEqual('anim.fadein(2)'); - }); - }); - - describe("applyNamespace", function() { - it('should insert the namespace only before the name part of the longname', function() { - var startName = 'lib.Panel#open', - endName = jsdoc.name.applyNamespace(startName, 'event'); - - expect(endName, 'lib.Panel#event:open'); - }); - - it(" should insert the namespace before a global name", function() { - var startName = 'maths/bigint', - endName = jsdoc.name.applyNamespace(startName, 'module'); - - expect(endName, 'module:maths/bigint'); - }); - - it('should treat quoted parts of the name as atomic and insert namespace before a quoted shortname', function() { - var startName = 'foo."*dont\'t.look~in#here!"', - endName = jsdoc.name.applyNamespace(startName, 'event'); - - expect(endName, 'foo.event:"*dont\'t.look~in#here!"'); - }); - - it('should not add another namespace if one already exists.', function() { - var startName = 'lib.Panel#event:open', - endName = jsdoc.name.applyNamespace(startName, 'event'); - - expect(endName, 'lib.Panel#event:open'); - }); - }); - - describe("splitName", function() { - it('should find the name and description.', function() { - var startName = 'ns.Page#"last \\"sentence\\"".words~sort(2) - This is a description. ', - parts = jsdoc.name.splitName(startName); - - expect(parts.name, 'ns.Page#"last \\"sentence\\"".words~sort(2)'); - expect(parts.description, 'This is a description.'); - }); - }); - - describe("resolve", function() { - // TODO: further tests (namespaces, modules, ...) - - // @event testing. - var event = '@event'; - var memberOf = '@memberof MyClass'; - var name = '@name A'; - function makeDoclet(bits) { - var comment = '/**\n' + bits.join('\n') + '\n*/'; - return new jsdoc.doclet.Doclet(comment, {}); - } - - // Test the basic @event that is not nested. - it('unnested @event gets resolved correctly', function() { - var doclet = makeDoclet([event, name]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toBeUndefined(); - expect(doclet.longname).toEqual('event:A'); - }); - - // test all permutations of @event @name [name] @memberof. - it('@event @name @memberof resolves correctly', function() { - var doclet = makeDoclet([event, name, memberOf]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('@event @memberof @name resolves correctly', function() { - var doclet = makeDoclet([event, memberOf, name]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('@name @event @memberof resolves correctly', function() { - var doclet = makeDoclet([name, event, memberOf]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('@name @memberof @event resolves correctly', function() { - var doclet = makeDoclet([name, memberOf, event]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('@memberof @event @name resolves correctly', function() { - var doclet = makeDoclet([memberOf, event, name]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('@memberof @name @event resolves correctly', function() { - var doclet = makeDoclet([memberOf, name, event]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - - // test all permutations of @event [name] @memberof - it('@event [name] @memberof resolves correctly', function() { - var doclet = makeDoclet(['@event A', memberOf]), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('@memberof @event [name] resolves correctly', function() { - var doclet = makeDoclet([memberOf, '@event A']), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - - // test full @event A.B - it('full @event definition works', function() { - var doclet = makeDoclet(['@event MyClass.A']), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - it('full @event definition with event: works', function() { - var doclet = makeDoclet(['@event MyClass.event:A']), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('event:A'); - expect(doclet.memberof).toEqual('MyClass'); - expect(doclet.longname).toEqual('MyClass.event:A'); - }); - - // a double-nested one just in case - it('@event @name MyClass.EventName @memberof somethingelse workse', function() { - var doclet = makeDoclet([event, '@name MyClass.A', '@memberof MyNamespace']), - out = jsdoc.name.resolve(doclet); - expect(doclet.name).toEqual('A'); - expect(doclet.memberof).toEqual('MyNamespace.MyClass'); - expect(doclet.longname).toEqual('MyNamespace.MyClass.event:A'); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/opts/argparser.js b/rsc/scripts/jsdoc/test/specs/jsdoc/opts/argparser.js deleted file mode 100644 index 5d4c1583..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/opts/argparser.js +++ /dev/null @@ -1,32 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("jsdoc/opts/argparser", function() { - var ArgParser = require('jsdoc/opts/argparser'), - argParser = new ArgParser(), - ourOptions; - - function trueFalse(v) { - var r = false; - if (v) { - if (v === 'true') { r = true; } - else if (v === 'false') { r = false; } - else { v = !!r; } - } - - return r; - } - - argParser.addOption('s', 'strict', true, 'Throw error on invalid input.', false, trueFalse); - argParser.addOption('n', 'name', true, 'The name of the project.', false); - - ourOptions = argParser.parse(['-s', 'true', '-n', 'true']); - - it('should coerce a true value if a coercer is provided', function() { - expect(ourOptions.strict).toBeDefined(); - expect(ourOptions.strict).toEqual(true); - }); - - it('should coerce a string value if no coercer is provided', function() { - expect(ourOptions.name).toBeDefined(); - expect(ourOptions.name).toEqual('true'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/opts/args.js b/rsc/scripts/jsdoc/test/specs/jsdoc/opts/args.js deleted file mode 100644 index bf924547..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/opts/args.js +++ /dev/null @@ -1,259 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("jsdoc/opts/args", function() { - var args = require('jsdoc/opts/args'); - var querystring = require('querystring'); - - it("should exist", function() { - expect(args).toBeDefined(); - expect(typeof args).toEqual("object"); - }); - - it("should export a 'parse' function", function() { - expect(args.parse).toBeDefined(); - expect(typeof args.parse).toEqual("function"); - }); - - it("should export a 'help' function", function() { - expect(args.help).toBeDefined(); - expect(typeof args.help).toEqual("function"); - }); - - it("should export a 'get' function", function() { - expect(args.get).toBeDefined(); - expect(typeof args.get).toEqual("function"); - }); - - describe("parse", function() { - it("should accept a '-t' option and return an object with a 'template' property", function() { - args.parse(['-t', 'mytemplate']); - var r = args.get(); - - expect(r.template).toEqual('mytemplate'); - }); - - it("should accept a '--template' option and return an object with a 'template' property", function() { - args.parse(['--template', 'mytemplate']); - var r = args.get(); - - expect(r.template).toEqual('mytemplate'); - }); - - it("should accept a '-c' option and return an object with a 'configure' property", function() { - args.parse(['-c', 'myconf.json']); - var r = args.get(); - - expect(r.configure).toEqual('myconf.json'); - }); - - it("should accept a '--configure' option and return an object with a 'configure' property", function() { - args.parse(['--configure', 'myconf.json']); - var r = args.get(); - - expect(r.configure).toEqual('myconf.json'); - }); - - it("should accept a '-e' option and return an object with a 'encoding' property", function() { - args.parse(['-e', 'ascii']); - var r = args.get(); - - expect(r.encoding).toEqual('ascii'); - }); - - it("should accept a '--encoding' option and return an object with a 'encoding' property", function() { - args.parse(['--encoding', 'ascii']); - var r = args.get(); - - expect(r.encoding).toEqual('ascii'); - }); - - it("should accept a '-T' option and return an object with a 'test' property", function() { - args.parse(['-T']); - var r = args.get(); - - expect(r.test).toEqual(true); - }); - - it("should accept a '--test' option and return an object with a 'test' property", function() { - args.parse(['--test']); - var r = args.get(); - - expect(r.test).toEqual(true); - }); - - it("should accept a '-d' option and return an object with a 'destination' property", function() { - args.parse(['-d', 'mydestination']); - var r = args.get(); - - expect(r.destination).toEqual('mydestination'); - }); - - it("should accept a '--destination' option and return an object with a 'destination' property", function() { - args.parse(['--destination', 'mydestination']); - var r = args.get(); - - expect(r.destination).toEqual('mydestination'); - }); - - it("should accept a '-p' option and return an object with a 'private' property", function() { - args.parse(['-p']); - var r = args.get(); - - expect(r['private']).toEqual(true); - }); - - it("should accept a '--private' option and return an object with a 'private' property", function() { - args.parse(['--private']); - var r = args.get(); - - expect(r['private']).toEqual(true); - }); - - it("should accept a '-r' option and return an object with a 'recurse' property", function() { - args.parse(['-r']); - var r = args.get(); - - expect(r.recurse).toEqual(true); - }); - - it("should accept a '--recurse' option and return an object with a 'recurse' property", function() { - args.parse(['--recurse']); - var r = args.get(); - - expect(r.recurse).toEqual(true); - }); - - it("should accept a '-l' option and return an object with a 'lenient' property", function() { - args.parse(['-l']); - var r = args.get(); - - expect(r.lenient).toEqual(true); - }); - - it("should accept a '--lenient' option and return an object with a 'lenient' property", function() { - args.parse(['--lenient']); - var r = args.get(); - - expect(r.lenient).toEqual(true); - }); - - it("should accept a '-h' option and return an object with a 'help' property", function() { - args.parse(['-h']); - var r = args.get(); - - expect(r.help).toEqual(true); - }); - - it("should accept a '--help' option and return an object with a 'help' property", function() { - args.parse(['--help']); - var r = args.get(); - - expect(r.help).toEqual(true); - }); - - it("should accept a '-X' option and return an object with a 'explain' property", function() { - args.parse(['-X']); - var r = args.get(); - - expect(r.explain).toEqual(true); - }); - - it("should accept a '--explain' option and return an object with a 'explain' property", function() { - args.parse(['--explain']); - var r = args.get(); - - expect(r.explain).toEqual(true); - }); - - it("should accept a '-q' option and return an object with a 'query' property", function() { - args.parse(['-q', 'foo=bar&fab=baz']); - var r = args.get(); - - expect(r.query).toEqual({ foo: 'bar', fab: 'baz' }); - }); - - it("should accept a '--query' option and return an object with a 'query' property", function() { - args.parse(['--query', 'foo=bar&fab=baz']); - var r = args.get(); - - expect(r.query).toEqual({ foo: 'bar', fab: 'baz' }); - }); - - it("should use type coercion on the 'query' property so it has real booleans and numbers", function() { - var obj = { - foo: 'fab', - bar: true, - baz: false, - qux: [1, -97] - }; - args.parse(['-q', querystring.stringify(obj)]); - var r = args.get(); - - expect(r.query).toEqual(obj); - }); - - it("should accept a '-t' option and return an object with a 'tutorials' property", function() { - args.parse(['-d', 'mytutorials']); - var r = args.get(); - - expect(r.destination).toEqual('mytutorials'); - }); - - it("should accept a '--tutorials' option and return an object with a 'tutorials' property", function() { - args.parse(['--tutorials', 'mytutorials']); - var r = args.get(); - - expect(r.tutorials).toEqual('mytutorials'); - }); - - it("should accept a '--verbose' option and return an object with a 'verbose' property", function() { - args.parse(['--verbose']); - var r = args.get(); - - expect(r.verbose).toEqual(true); - }); - - it("should accept a '--match' option and return an object with a 'match' property", function() { - args.parse(['--match', '.*tag']); - var r = args.get(); - - expect(r.match).toEqual('.*tag'); - }); - - it("should accept multiple '--match' options and return an object with a 'match' property", function() { - args.parse(['--match', '.*tag', '--match', 'parser']); - var r = args.get(); - - expect(r.match).toEqual(['.*tag', 'parser']); - }); - - it("should accept a '--nocolor' option and return an object with a 'nocolor' property", function() { - args.parse(['--nocolor']); - var r = args.get(); - - expect(r.nocolor).toEqual(true); - }); - - it("should accept a '-v' option and return an object with a 'version' property", function() { - args.parse(['-v']); - var r = args.get(); - - expect(r.version).toEqual(true); - }); - - it("should accept a '--version' option and return an object with a 'version' property", function() { - args.parse(['--version']); - var r = args.get(); - - expect(r.version).toEqual(true); - }); - - it("should accept a naked option (i.e. no '-') and return an object with a '_' property", function() { - args.parse(['myfile1', 'myfile2']); - var r = args.get(); - - expect(r._).toEqual(['myfile1', 'myfile2']); - }); - - //TODO: tests for args that must have values - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/path.js b/rsc/scripts/jsdoc/test/specs/jsdoc/path.js deleted file mode 100644 index 90952b3b..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/path.js +++ /dev/null @@ -1,95 +0,0 @@ -/*global beforeEach: true, describe: true, expect: true, it: true, spyOn: true, xdescribe: true */ - -describe('jsdoc/path', function() { - var os = require('os'); - var path = require('jsdoc/path'); - var standardPath = require('path'); - - it('should exist', function() { - expect(path).toBeDefined(); - expect(typeof path).toEqual('object'); - }); - - it('should export all functions in the "path" module', function() { - Object.keys(standardPath).forEach(function(item) { - if (typeof standardPath[item] === 'function') { - expect(path[item]).toBeDefined(); - expect(typeof path[item]).toEqual('function'); - } - }); - }); - - it('should export a "commonPrefix" function', function() { - expect(path.commonPrefix).toBeDefined(); - expect(typeof path.commonPrefix).toEqual('function'); - }); - - it('should export a "getResourcePath" function', function() { - expect(path.getResourcePath).toBeDefined(); - expect(typeof path.getResourcePath).toEqual('function'); - }); - - describe('commonPrefix', function() { - beforeEach(function() { - spyOn(process, 'cwd').andCallFake(function() { - return os.platform().match(/^win/) ? 'C:\\Users\\jsdoc' : '/Users/jsdoc'; - }); - }); - - it('finds the correct prefix for a group of relative paths', function() { - var cwd = process.cwd().split(path.sep); - var paths = [ - path.join('foo', 'bar', 'baz', 'qux.js'), - path.join('foo', 'bar', 'baz', 'quux.js'), - path.join('foo', 'bar', 'baz.js') - ]; - // we expect a trailing slash - var expected = cwd.concat('foo', 'bar', '').join(path.sep); - - expect( path.commonPrefix(paths) ).toEqual(expected); - }); - - it('finds the correct prefix for a group of absolute paths', function() { - var cwd = process.cwd().split(path.sep); - var paths = [ - cwd.concat('foo', 'bar', 'baz', 'qux.js').join(path.sep), - cwd.concat('foo', 'bar', 'baz', 'quux.js').join(path.sep), - cwd.concat('foo', 'bar', 'baz.js').join(path.sep) - ]; - // we expect a trailing slash - var expected = cwd.concat('foo', 'bar', '').join(path.sep); - - expect( path.commonPrefix(paths) ).toEqual(expected); - }); - - it('finds the correct prefix for a group of absolute paths and dotted relative paths', - function() { - var cwd = process.cwd().split(path.sep); - var paths = [ - path.join('..', 'jsdoc', 'foo', 'bar', 'baz', 'qux', 'quux', 'test.js'), - cwd.concat('foo', 'bar', 'bazzy.js').join(path.sep), - path.join('..', '..', 'Users', 'jsdoc', 'foo', 'bar', 'foobar.js') - ]; - // we expect a trailing slash - var expected = cwd.concat('foo', 'bar', '').join(path.sep); - - expect( path.commonPrefix(paths) ).toEqual(expected); - }); - - it('returns an empty string when there is no common prefix', function() { - // skip on Windows, since the paths share a drive letter at the start - if ( !os.platform().match(/^win/) ) { - var paths = [ - path.join('foo', 'bar', 'baz', 'qux.js'), - path.join('..', '..', 'Library', 'foo', 'bar', 'baz.js') - ]; - - expect( path.commonPrefix(paths) ).toEqual(''); - } - }); - }); - - xdescribe('getResourcePath', function() { - // TODO - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/plugins.js b/rsc/scripts/jsdoc/test/specs/jsdoc/plugins.js deleted file mode 100644 index 2db3dd19..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/plugins.js +++ /dev/null @@ -1,20 +0,0 @@ -/*global describe: true, expect: true, it: true, xdescribe: true */ - -describe("jsdoc/plugins", function() { - var plugins = require('jsdoc/plugins'); - - it("should exist", function() { - expect(plugins).toBeDefined(); - expect(typeof plugins).toEqual('object'); - }); - - it("should export an 'installPlugins' function", function() { - expect(plugins.installPlugins).toBeDefined(); - expect(typeof plugins.installPlugins).toEqual('function'); - }); - - - xdescribe("installPlugins", function() { - // TODO - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/readme.js b/rsc/scripts/jsdoc/test/specs/jsdoc/readme.js deleted file mode 100644 index 51af2f75..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/readme.js +++ /dev/null @@ -1,14 +0,0 @@ -describe("jsdoc/readme", function() { - var jsdoc = {readme: require('jsdoc/readme') }, - html = (new jsdoc.readme('test/fixtures/markdowntest.md')).html; - - it("should parse html out of markdown", function() { - expect(html).toBeDefined(); - expect(typeof html).toEqual("string"); - expect(html).toContain(''); - expect(html).toContain('

      '); - expect(html).toContain('

      '); - expect(html).toContain('

    • '); - }); - -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/src/filter.js b/rsc/scripts/jsdoc/test/specs/jsdoc/src/filter.js deleted file mode 100644 index c34d0aae..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/src/filter.js +++ /dev/null @@ -1,20 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("jsdoc/src/filter", function() { - var filter = new (require('jsdoc/src/filter').Filter)({ - includePattern: new RegExp(".+\\.js(doc)?$"), - excludePattern: new RegExp("(^|\\/)_"), - exclude: ['.ignore', 'scratch/conf.js'] - }); - - var files = ['yes.js', '/yes.jsdoc', '/_nope.js', '.ignore', process.cwd() + '/scratch/conf.js']; - - files = files.filter(function($) { - return filter.isIncluded($); - }); - - it("should return the correct source files", function() { - expect(files.length).toEqual(2); - expect(files.indexOf("yes.js")).toBeGreaterThan(-1); - expect(files.indexOf("/yes.jsdoc")).toBeGreaterThan(-1); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/src/handlers.js b/rsc/scripts/jsdoc/test/specs/jsdoc/src/handlers.js deleted file mode 100644 index f43ac711..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/src/handlers.js +++ /dev/null @@ -1,55 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("jsdoc/src/handlers", function() { - var jsdoc = {src: { parser: require('jsdoc/src/parser')}}, - testParser = new jsdoc.src.parser.Parser(), - handlers = require('jsdoc/src/handlers'); - - handlers.attachTo(testParser); - - it("should exist", function() { - expect(handlers).toBeDefined(); - expect(typeof handlers).toEqual("object"); - }); - - it("should export an 'attachTo' function", function() { - expect(handlers.attachTo).toBeDefined(); - expect(typeof handlers.attachTo).toEqual("function"); - }); - - describe("attachTo", function() { - it("should attach a 'jsdocCommentFound' handler to the parser", function() { - var callbacks = testParser.listeners("jsdocCommentFound"); - expect(callbacks).toBeDefined(); - expect(callbacks.length).toEqual(1); - expect(typeof callbacks[0]).toEqual("function"); - }); - - it("should attach a 'symbolFound' handler to the parser", function() { - var callbacks = testParser.listeners("symbolFound"); - expect(callbacks).toBeDefined(); - expect(callbacks.length).toEqual(1); - expect(typeof callbacks[0]).toEqual("function"); - }); - - it("should attach a 'fileComplete' handler to the parser", function() { - var callbacks = testParser.listeners("fileComplete"); - expect(callbacks).toBeDefined(); - expect(callbacks.length).toEqual(1); - expect(typeof callbacks[0]).toEqual("function"); - }); - }); - - describe("jsdocCommentFound handler", function() { - var sourceCode = 'javascript:/** @name bar */', - result = testParser.parse(sourceCode); - - it("should create a doclet for comments with '@name' tags", function() { - expect(result.length).toEqual(1); - expect(result[0].name).toEqual('bar'); - }); - }); - - describe("symbolFound handler", function() { - //TODO - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/src/parser.js b/rsc/scripts/jsdoc/test/specs/jsdoc/src/parser.js deleted file mode 100644 index d1794dee..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/src/parser.js +++ /dev/null @@ -1,123 +0,0 @@ -/*global beforeEach: true, describe: true, expect: true, it: true, jasmine: true, xdescribe: true, xit: true */ -describe("jsdoc/src/parser", function() { - var jsdoc = {src: { parser: require('jsdoc/src/parser')}}; - - it("should exist", function() { - expect(jsdoc.src.parser).toBeDefined(); - expect(typeof jsdoc.src.parser).toEqual("object"); - }); - - it("should export a 'Parser' constructor", function() { - expect(jsdoc.src.parser.Parser).toBeDefined(); - expect(typeof jsdoc.src.parser.Parser).toEqual("function"); - }); - - describe("Parser", function() { - var parser; - - function newParser() { - parser = new jsdoc.src.parser.Parser(); - } - - it("should have a 'parse' function", function() { - expect(jsdoc.src.parser.Parser.prototype.parse).toBeDefined(); - expect(typeof jsdoc.src.parser.Parser.prototype.parse).toEqual("function"); - }); - - it("should have a 'results' function", function() { - expect(jsdoc.src.parser.Parser.prototype.results).toBeDefined(); - expect(typeof jsdoc.src.parser.Parser.prototype.results).toEqual("function"); - }); - - describe("parse", function() { - beforeEach(newParser); - - it("should fire 'parseBegin' events before it parses any files", function() { - var spy = jasmine.createSpy(), - sourceFiles = ["javascript:/** @name foo */"]; - - parser.on("parseBegin", spy).parse(sourceFiles); - expect(spy).toHaveBeenCalled(); - expect(spy.mostRecentCall.args[0].sourcefiles).toBe(sourceFiles); - }); - - it("should allow 'parseBegin' handlers to modify the list of source files", function() { - var sourceCode = "javascript:/** @name foo */", - newFiles = ["[[replaced]]"], - evt; - - function handler(e) { - e.sourcefiles = newFiles; - evt = e; - } - - parser.on('parseBegin', handler).parse(sourceCode); - expect(evt.sourcefiles).toBe(newFiles); - }); - - it("should fire 'jsdocCommentFound' events when parsing source containing jsdoc comments", function() { - var spy = jasmine.createSpy(), - sourceCode = ['javascript:/** @name bar */']; - parser.on('jsdocCommentFound', spy).parse(sourceCode); - expect(spy).toHaveBeenCalled(); - expect(spy.mostRecentCall.args[0].comment).toEqual("/** @name bar */"); - }); - - it("should fire 'symbolFound' events when parsing source containing named symbols", function() { - var spy = jasmine.createSpy(), - sourceCode = 'javascript:var foo = 1'; - parser.on('symbolFound', spy).parse(sourceCode); - expect(spy).toHaveBeenCalled(); - }); - - it("should fire 'parseComplete' events after it finishes parsing files", function() { - var spy = jasmine.createSpy(), - sourceCode = ['javascript:var bar = false;']; - parser.on('parseComplete', spy).parse(sourceCode); - expect(spy).toHaveBeenCalled(); - expect(spy.mostRecentCall.args[0].sourcefiles).toEqual(["[[string0]]"]); - }); - - it("should be able to parse its own source file", function() { - var fs = require('jsdoc/fs'), - path = require('path'), - parserSrc = 'javascript:' + fs.readFileSync( path.join(__dirname, - 'lib', 'jsdoc', 'src', 'parser.js'), 'utf8' ), - parse = function() { - parser.parse(parserSrc); - }; - - expect(parse).not.toThrow(); - }); - }); - - describe("results", function() { - beforeEach(newParser); - - xit("contains an empty array before files are parsed", function() { - // TODO - }); - - xit("contains an array of doclets after files are parsed", function() { - - }); - - it("should reflect comment changes made by 'jsdocCommentFound' handlers", function() { - // we test both POSIX and Windows line endings - var source = "javascript:/**\n * replaceme\r\n * @module foo\n */\n\n" + - "/**\n * replaceme\n */\nvar bar;"; - - parser.on('jsdocCommentFound', function(e) { - e.comment = e.comment.replace('replaceme', 'REPLACED!'); - }); - require("jsdoc/src/handlers").attachTo(parser); - - parser.parse(source); - parser.results().forEach(function(doclet) { - expect(doclet.comment).not.toMatch('replaceme'); - expect(doclet.comment).toMatch('REPLACED!'); - }); - }); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/src/scanner.js b/rsc/scripts/jsdoc/test/specs/jsdoc/src/scanner.js deleted file mode 100644 index 3203c2aa..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/src/scanner.js +++ /dev/null @@ -1,21 +0,0 @@ -/*global describe: true, env: true, expect: true, it: true */ -describe("jsdoc/src/scanner", function() { - var scanner = new (require('jsdoc/src/scanner').Scanner)(), - filter = new (require('jsdoc/src/filter').Filter)({ - includePattern: new RegExp(".+\\.js(doc)?$"), - excludePattern: new RegExp("(^|\\/|\\\\)_") - }), - path = require('path'), - sourceFiles = scanner.scan([path.join(__dirname, 'test', 'fixtures', 'src')], 3, filter); - - sourceFiles = sourceFiles.map(function($) { - return path.relative(__dirname, $); - }); - - it("should return the correct source files", function() { - expect(sourceFiles.length).toEqual(3); - expect(sourceFiles.indexOf(path.join('test', 'fixtures', 'src', 'one.js'))).toBeGreaterThan(-1); - expect(sourceFiles.indexOf(path.join('test', 'fixtures', 'src', 'two.js'))).toBeGreaterThan(-1); - expect(sourceFiles.indexOf(path.join('test', 'fixtures', 'src', 'dir1', 'three.js'))).toBeGreaterThan(-1); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tag.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tag.js deleted file mode 100644 index a324a9c3..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tag.js +++ /dev/null @@ -1,162 +0,0 @@ -/*global describe: true, env: true, it: true */ -describe("jsdoc/tag", function() { - var jsdoc = { - tag: require('jsdoc/tag'), - dictionary: require('jsdoc/tag/dictionary'), - type: require('jsdoc/tag/type') - }; - - it('should exist', function() { - expect(jsdoc.tag).toBeDefined(); - expect(typeof jsdoc.tag).toBe('object'); - }); - - it('should export a Tag function', function() { - expect(jsdoc.tag.Tag).toBeDefined(); - expect(typeof jsdoc.tag.Tag).toBe('function'); - }); - - describe('Tag', function() { - var meta = {lineno: 1, filename: 'asdf.js'}, - desc = 'lalblakd lkjasdlib\n lija', - text = '{!number} [foo=1] - ' + desc, - textEg = 'Asdf\n' + - ' * myFunction(1, 2); // returns 3\n' + - ' * myFunction(3, 4); // returns 7\n'; - var tagArg = new jsdoc.tag.Tag('arg ', text, meta), // <-- a symonym of param, space in the title. - tagParam = new jsdoc.tag.Tag('param', '[foo=1]', meta), // no type, but has optional and defaultvalue. - tagEg = new jsdoc.tag.Tag('example', textEg, meta), // <-- for keepsWhitespace - tagType = new jsdoc.tag.Tag('type', 'MyType ', meta); // <-- for onTagText - - it("should have a 'originalTitle' property, a string", function() { - expect(tagArg.originalTitle).toBeDefined(); - expect(typeof tagArg.originalTitle).toBe('string'); - }); - - it("'originalTitle' property should be the initial tag title, trimmed of whitespace", function() { - expect(tagArg.originalTitle).toBe('arg'); - expect(tagEg.originalTitle).toBe('example'); - }); - - it("should have a 'title' property, a string", function() { - expect(tagArg.title).toBeDefined(); - expect(typeof tagArg.title).toBe('string'); - }); - - it("'title' property should be the normalised tag title", function() { - expect(tagArg.title).toBe(jsdoc.dictionary.normalise(tagArg.originalTitle)); - expect(tagEg.title).toBe(jsdoc.dictionary.normalise(tagEg.originalTitle)); - }); - - it("should have a 'text' property. a string", function () { - expect(tagArg.text).toBeDefined(); - expect(typeof tagArg.text).toBe('string'); - }); - - it("should have a 'value' property", function () { - expect(tagArg.value).toBeDefined(); - expect(tagEg.value).toBeDefined(); - expect(tagType.value).toBeDefined(); - }); - - describe("'text' property", function() { - it("'text' property should be the trimmed tag text, with all leading and trailing space removed unless tagDef.keepsWhitespace", function() { - // @example has keepsWhitespace, @param doesn't. - // should realy use module:jsdoc/tag~trim here but it's private. - expect(tagArg.text).toBe(text.replace(/^\s+|\s+$/g, '')); - expect(tagEg.text).toBe(textEg.replace(/^[\n\r\f]+|[\n\r\f]+$/g, '')); - }); - - it("'text' property should have onTagText run on it if it has it.", function() { - var def = jsdoc.dictionary.lookUp('type'); - expect(def.onTagText).toBeDefined(); - expect(typeof def.onTagText).toBe('function'); - - // @type adds {} around the type if necessary. - expect(tagType.text).toBeDefined(); - expect(tagType.text).toBe(def.onTagText('MyType')); - }); - }); - - describe("'value' property", function() { - it("'value' property should equal tag text if tagDef.canHaveType and canHaveName are both false", function() { - // @example can't have type or name - expect(typeof tagEg.value).toBe('string'); - expect(tagEg.value).toBe(tagEg.text); - }); - - it("'value' property should be an object if tagDef can have type or name", function () { - expect(typeof tagType.value).toBe('object'); - expect(typeof tagArg.value).toBe('object'); - }); - - function verifyTagType(tag) { - var def = jsdoc.dictionary.lookUp(tag.title); - expect(def).not.toBe(false); - var info = jsdoc.type.parse(tag.text, def.canHaveName, def.canHaveType); - - var props_that_should_be_copied = ['optional', 'nullable', 'variable', 'defaultvalue']; - for (var i = 0; i < props_that_should_be_copied.length; ++i) { - var prop = props_that_should_be_copied[i]; - if (info.hasOwnProperty(prop)) { - expect(tag.value[prop]).toBe(info[prop]); - } - } - if (info.type && info.type.length) { - expect(tag.value.type).toBeDefined(); - expect(typeof tag.value.type).toBe('object'); - expect(tag.value.type.names).toBeDefined(); - expect(tag.value.type.names).toEqual(info.type); - } - } - it("if the tag has a type, tag.value should contain the type information", function() { - // we assume jsdoc/tag/type.parse works (it has its own tests to verify this); - verifyTagType(tagType); - verifyTagType(tagArg); - verifyTagType(tagParam); - }); - - it("if the tag has a description beyond the name/type, this should be in tag.value.description", function() { - expect(tagType.value.description).not.toBeDefined(); - - expect(tagArg.value.description).toBeDefined(); - expect(tagArg.value.description).toBe(desc); - }); - - it("if the tag can have a name, it should be stored in tag.value.name", function() { - expect(tagArg.value.name).toBeDefined(); - expect(tagArg.value.name).toBe('foo'); - - expect(tagType.value.name).not.toBeDefined(); - }); - }); - - // further tests for this sort of thing are in jsdoc/tag/validator.js tests. - describe("tag validating", function() { - /*jshint evil: true */ - var lenient = !!env.opts.lenient; - - function badTag() { - var tag = new jsdoc.tag.Tag("name"); - return tag; - } - - afterEach(function() { - env.opts.lenient = lenient; - }); - - it("throws an exception for bad tags if the lenient option is not enabled", function() { - env.opts.lenient = false; - - expect(badTag).toThrow(); - }); - - it("doesn't throw an exception for bad tags if the lenient option is enabled", function() { - spyOn(console, 'log'); - env.opts.lenient = true; - - expect(badTag).not.toThrow(); - }); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/dictionary.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tag/dictionary.js deleted file mode 100644 index b6e0544c..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/dictionary.js +++ /dev/null @@ -1,98 +0,0 @@ -describe('jsdoc/tag/dictionary', function() { - var dictionary = require('jsdoc/tag/dictionary'); - - it('should exist', function() { - expect(dictionary).toBeDefined(); - expect(typeof dictionary).toBe('object'); - }); - - it('should export a defineTag function', function() { - expect(dictionary.defineTag).toBeDefined(); - expect(typeof dictionary.defineTag).toBe('function'); - }); - - it('should export a lookUp function', function() { - expect(dictionary.lookUp).toBeDefined(); - expect(typeof dictionary.lookUp).toBe('function'); - }); - - it('should export a isNamespace function', function() { - expect(dictionary.isNamespace).toBeDefined(); - expect(typeof dictionary.isNamespace).toBe('function'); - }); - - it('should export a normalise function', function() { - expect(dictionary.normalise).toBeDefined(); - expect(typeof dictionary.normalise).toBe('function'); - }); - - // TODO: should really remove this tag from the dictionary after, but how? - var tagOptions = { - canHaveValue: true, - isNamespace: true - }, - tagTitle = 'testTag', - tagSynonym = 'testTag2'; - var def = dictionary.defineTag(tagTitle, tagOptions).synonym(tagSynonym); - // Should really test TagDefinition but they are private. - // Instead, we'll just tests all the properties we expect of it. - describe("defineTag", function() { - - // Since TagDefinition is private, I'll just test for its properties here. - it("returns an object with 'title' property", function() { - expect(typeof def).toBe('object'); - // how to test? - expect(def.title).toBeDefined(); - expect(typeof def.title).toBe('string'); - expect(def.title).toBe(dictionary.normalise(tagTitle)); - }); - - it("returned object has all the tag properties copied over", function() { - for (var prop in tagOptions) { - if (tagOptions.hasOwnProperty(prop)) { - expect(def[prop]).toBe(tagOptions[prop]); - } - } - }); - }); - - describe("lookUp", function() { - it("retrieves definition when using the tag's canonical name", function() { - expect(dictionary.lookUp(tagTitle)).toBe(def); - }); - - it("retrieves definition when using a synonym", function() { - expect(dictionary.lookUp(tagSynonym)).toBe(def); - }); - - it("returns FALSE when a tag is not found", function() { - expect(dictionary.lookUp('lkjas1l24jk')).toBe(false); - }); - }); - - describe("isNamespace", function() { - it("returns whether a tag is a namespace when using its canonical name", function() { - expect(dictionary.isNamespace(tagTitle)).toBe(true); - }); - - it("returns whether a tag is a namespace when using its synonym", function() { - expect(dictionary.isNamespace(tagSynonym)).toBe(true); - }); - - it("non-existent tags or non-namespace tags should return false", function() { - expect(dictionary.isNamespace('see')).toBe(false); - expect(dictionary.isNamespace('lkjasd90034')).toBe(false); - }); - }); - - describe("normalise", function() { - it("should return the tag's title if it is not a synonym", function() { - expect(dictionary.normalise('FooBar')).toBe('foobar'); - expect(dictionary.normalise(tagTitle)).toBe(def.title); - }); - - it("should return the canonical name of a tag if the synonym is normalised", function() { - expect(dictionary.normalise(tagSynonym)).toBe(def.title); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/dictionary/definitions.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tag/dictionary/definitions.js deleted file mode 100644 index 4abae895..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/dictionary/definitions.js +++ /dev/null @@ -1,15 +0,0 @@ -describe('jsdoc/tag/dictionary/definitions', function() { - var type = require('jsdoc/tag/dictionary/definitions'); - - it('should exist', function() { - expect(type).toBeDefined(); - expect(typeof type).toBe('object'); - }); - - it('should export a defineTags function', function() { - expect(type.defineTags).toBeDefined(); - expect(typeof type.defineTags).toBe('function'); - }); - // whole bit of dictionary.defineTags...but it just calls dictionary.defineTag - // and if I validate that then the rest is automatically validated? -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/inline.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tag/inline.js deleted file mode 100644 index de206a76..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/inline.js +++ /dev/null @@ -1,211 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ - -describe('jsdoc/tag/inline', function() { - var jsdoc = { - tag: { - inline: require('jsdoc/tag/inline') - } - }; - - it('should exist', function() { - expect(jsdoc.tag.inline).toBeDefined(); - expect(typeof jsdoc.tag.inline).toBe('object'); - }); - - it('should export a replaceInlineTag function', function() { - expect(jsdoc.tag.inline.replaceInlineTag).toBeDefined(); - expect(typeof jsdoc.tag.inline.replaceInlineTag).toBe('function'); - }); - - it('should export an extractInlineTag function', function() { - expect(jsdoc.tag.inline.extractInlineTag).toBeDefined(); - expect(typeof jsdoc.tag.inline.replaceInlineTag).toBe('function'); - }); - - describe('replaceInlineTag', function() { - it('should throw if the tag is matched and the replacer is invalid', function() { - function badReplacerUndefined() { - jsdoc.tag.inline.replaceInlineTag('{@foo tag}', 'foo'); - } - - function badReplacerString() { - jsdoc.tag.inline.replaceInlineTag('{@foo tag}', 'foo', 'hello'); - } - - expect(badReplacerUndefined).toThrow(); - expect(badReplacerString).toThrow(); - }); - - it('should not find anything if there is no text in braces', function() { - var replacer = jasmine.createSpy('replacer'); - var result = jsdoc.tag.inline.replaceInlineTag('braceless text', 'foo', replacer); - expect(replacer).not.toHaveBeenCalled(); - }); - - it('should cope with bad escapement at the end of the string', function() { - var replacer = jasmine.createSpy('replacer'); - var result = jsdoc.tag.inline.replaceInlineTag('bad {@foo escapement \\', 'foo', - replacer); - expect(replacer).not.toHaveBeenCalled(); - }); - - it('should work if the tag is the entire string', function() { - function replacer(string, tagInfo) { - expect(string).toBe('{@foo text in braces}'); - expect(tagInfo.completeTag).toBe('{@foo text in braces}'); - expect(tagInfo.text).toBe('text in braces'); - - return tagInfo.completeTag; - } - - var result = jsdoc.tag.inline.replaceInlineTag('{@foo text in braces}', 'foo', - replacer); - expect(result.tags[0]).toBeDefined(); - expect(typeof result.tags[0]).toBe('object'); - expect(result.tags[0].tag).toBe('foo'); - expect(result.tags[0].text).toBe('text in braces'); - expect(result.newString).toBe('{@foo text in braces}'); - }); - - it('should work if the tag is at the beginning of the string', function() { - function replacer(string, tagInfo) { - expect(string).toBe('{@foo test string} ahoy'); - expect(tagInfo.completeTag).toBe('{@foo test string}'); - expect(tagInfo.text).toBe('test string'); - - return string; - } - - var result = jsdoc.tag.inline.replaceInlineTag('{@foo test string} ahoy', 'foo', - replacer); - expect(result.tags[0]).toBeDefined(); - expect(typeof result.tags[0]).toBe('object'); - expect(result.tags[0].tag).toBe('foo'); - expect(result.tags[0].text).toBe('test string'); - expect(result.newString).toBe('{@foo test string} ahoy'); - }); - - it('should work if the tag is in the middle of the string', function() { - function replacer(string, tagInfo) { - expect(string).toBe('a {@foo test string} yay'); - expect(tagInfo.completeTag).toBe('{@foo test string}'); - expect(tagInfo.text).toBe('test string'); - - return string; - } - - var result = jsdoc.tag.inline.replaceInlineTag('a {@foo test string} yay', 'foo', - replacer); - expect(result.tags[0]).toBeDefined(); - expect(typeof result.tags[0]).toBe('object'); - expect(result.tags[0].tag).toBe('foo'); - expect(result.tags[0].text).toBe('test string'); - expect(result.newString).toBe('a {@foo test string} yay'); - }); - - it('should work if the tag is at the end of the string', function() { - function replacer(string, tagInfo) { - expect(string).toBe('a {@foo test string}'); - expect(tagInfo.completeTag).toBe('{@foo test string}'); - expect(tagInfo.text).toBe('test string'); - - return string; - } - - var result = jsdoc.tag.inline.replaceInlineTag('a {@foo test string}', 'foo', replacer); - expect(result.tags[0]).toBeDefined(); - expect(typeof result.tags[0]).toBe('object'); - expect(result.tags[0].tag).toBe('foo'); - expect(result.tags[0].text).toBe('test string'); - expect(result.newString).toBe('a {@foo test string}'); - }); - - it('should replace the string with the specified value', function() { - function replacer() { - return 'REPLACED!'; - } - - var result = jsdoc.tag.inline.replaceInlineTag('a {@foo test string}', 'foo', replacer); - expect(result.newString).toBe('REPLACED!'); - }); - - it('should process all occurrences of a tag', function() { - function replacer(string, tagInfo) { - return string.replace(tagInfo.completeTag, 'stuff'); - } - - var result = jsdoc.tag.inline.replaceInlineTag('some {@foo text} with multiple ' + - '{@foo tags}', 'foo', replacer); - - expect(result.tags[0]).toBeDefined(); - expect(typeof result.tags[0]).toBe('object'); - expect(result.tags[0].tag).toBe('foo'); - expect(result.tags[0].text).toBe('text'); - - expect(result.tags[1]).toBeDefined(); - expect(typeof result.tags[1]).toBe('object'); - expect(result.tags[1].tag).toBe('foo'); - expect(result.tags[1].text).toBe('tags'); - - expect(result.newString).toBe('some stuff with multiple stuff'); - }); - - }); - - // largely covered by the replaceInlineTag tests - describe('replaceInlineTags', function() { - it('should work with an empty replacer object', function() { - var replacers = {}; - var text = 'some {@foo text} to parse'; - - var result = jsdoc.tag.inline.replaceInlineTags(text, replacers); - expect(result.newString).toBe(text); - }); - - it('should work with an object with one replacer', function() { - var text = 'some {@foo text} with {@bar multiple} tags'; - var replacers = { - foo: function(string, tagInfo) { - expect(tagInfo.completeTag).toBe('{@foo text}'); - expect(tagInfo.text).toBe('text'); - return string.replace(tagInfo.completeTag, 'stuff'); - } - }; - - var result = jsdoc.tag.inline.replaceInlineTags(text, replacers); - expect(result.newString).toBe('some stuff with {@bar multiple} tags'); - - }); - - it('should work with an object with multiple replacers', function() { - var text = 'some {@foo text} with {@bar multiple} tags'; - var replacers = { - foo: function(string, tagInfo) { - expect(tagInfo.completeTag).toBe('{@foo text}'); - expect(tagInfo.text).toBe('text'); - return string.replace(tagInfo.completeTag, 'stuff'); - }, - bar: function(string, tagInfo) { - expect(tagInfo.completeTag).toBe('{@bar multiple}'); - expect(tagInfo.text).toBe('multiple'); - return string.replace(tagInfo.completeTag, 'awesome'); - } - }; - - var result = jsdoc.tag.inline.replaceInlineTags(text, replacers); - expect(result.newString).toBe('some stuff with awesome tags'); - }); - }); - - // largely covered by the replaceInlineTag tests - describe('extractInlineTag', function() { - it('should work when a tag is specified', function() { - var result = jsdoc.tag.inline.extractInlineTag('some {@tagged text}', 'tagged'); - expect(result.tags[0]).toBeDefined(); - expect(typeof result.tags[0]).toBe('object'); - expect(result.tags[0].tag).toBe('tagged'); - expect(result.tags[0].text).toBe('text'); - expect(result.newString).toBe('some'); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/type.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tag/type.js deleted file mode 100644 index dd9105f3..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/type.js +++ /dev/null @@ -1,247 +0,0 @@ -/*global describe: true, expect: true, it: true */ - -function buildText(type, name, desc) { - var text = ''; - if (type) { - text += '{' + type + '}'; - if (name || desc) { - text += ' '; - } - } - - if (name) { - text += name; - if (desc) { - text += ' '; - } - } - - if (desc) { - text += desc; - } - - return text; -} - -describe('jsdoc/tag/type', function() { - var jsdoc = { - tag: { - type: require('jsdoc/tag/type') - } - }; - - it('should exist', function() { - expect(jsdoc.tag.type).toBeDefined(); - expect(typeof jsdoc.tag.type).toBe('object'); - }); - - it('should export a parse function', function() { - expect(jsdoc.tag.type.parse).toBeDefined(); - expect(typeof jsdoc.tag.type.parse).toBe('function'); - }); - - describe('parse', function() { - it('should return an object with name, type, and text properties', function() { - var info = jsdoc.tag.type.parse(''); - expect(info.name).toBeDefined(); - expect(info.type).toBeDefined(); - expect(info.text).toBeDefined(); - }); - - it('should not extract a name or type if canHaveName and canHaveType are not set', function() { - var desc = '{number} foo The foo parameter.'; - var info = jsdoc.tag.type.parse(desc); - expect(info.type).toEqual([]); - expect(info.name).toBe(''); - expect(info.text).toBe(desc); - }); - - it('should extract a name, but not a type, if canHaveName === true and canHaveType === false', function() { - var name = 'bar'; - var desc = 'The bar parameter.'; - var info = jsdoc.tag.type.parse( buildText(null, name, desc), true, false ); - expect(info.type).toEqual([]); - expect(info.name).toBe(name); - expect(info.text).toBe(desc); - }); - - it('should extract a type, but not a name, if canHaveName === false and canHaveType === true', function() { - var type = 'boolean'; - var desc = 'Set to true on alternate Thursdays.'; - var info = jsdoc.tag.type.parse( buildText(type, null, desc), false, true ); - expect(info.type).toEqual([type]); - expect(info.name).toBe(''); - expect(info.text).toBe(desc); - }); - - it('should extract a name and type if canHaveName and canHaveType are true', function() { - var type = 'string'; - var name = 'baz'; - var desc = 'The baz parameter.'; - var info = jsdoc.tag.type.parse( buildText(type, name, desc), true, true ); - expect(info.type).toEqual([type]); - expect(info.name).toBe(name); - expect(info.text).toBe(desc); - }); - - it('should report optional types correctly no matter which syntax we use', function() { - var desc = '{string} [foo]'; - var info = jsdoc.tag.type.parse(desc, true, true); - expect(info.optional).toBe(true); - - desc = '{string=} [foo]'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.optional).toBe(true); - - desc = '[foo]'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.optional).toBe(true); - }); - - it('should return the types as an array', function() { - var desc = '{string} foo'; - var info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['string'] ); - }); - - it('should recognize the entire list of possible types', function() { - var desc = '{(string|number)} foo'; - var info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['string', 'number'] ); - - desc = '{ ( string | number ) } foo'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['string', 'number'] ); - - desc = '{ ( string | number)} foo'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['string', 'number'] ); - - desc = '{(string|number|boolean|function)} foo'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['string', 'number', 'boolean', 'function'] ); - }); - - it('should not find any type if there is no text in braces', function() { - var desc = 'braceless text'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type).toEqual([]); - }); - - it('should cope with bad escapement at the end of the string', function() { - var desc = 'bad {escapement \\'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type).toEqual([]); - expect(info.text).toBe(desc); - }); - - it('should handle escaped braces correctly', function() { - var desc = '{weirdObject."with\\}AnnoyingProperty"}'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type[0]).toBe('weirdObject."with}AnnoyingProperty"'); - }); - - it('should work if the type expression is the entire string', function() { - var desc = '{textInBraces}'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type[0]).toBe('textInBraces'); - }); - - it('should work if the type expression is at the beginning of the string', function() { - var desc = '{testString} ahoy'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type[0]).toBe('testString'); - expect(info.text).toBe('ahoy'); - }); - - it('should work if the type expression is in the middle of the string', function() { - var desc = 'a {testString} yay'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type[0]).toBe('testString'); - expect(info.text).toBe('a yay'); - }); - - it('should work if the tag is at the end of the string', function() { - var desc = 'a {testString}'; - var info = jsdoc.tag.type.parse(desc, false, true); - expect(info.type[0]).toBe('testString'); - expect(info.text).toBe('a'); - }); - - it('should work when there are nested braces', function() { - var desc = 'some {{double}} braces'; - var info = jsdoc.tag.type.parse(desc, false, true); - // we currently stringify all record types as 'Object' - expect(info.type[0]).toBe('Object'); - expect(info.text).toBe('some braces'); - }); - - it('should override the type expression if an inline @type tag is specified', function() { - var desc = '{Object} cookie {@type Monster}'; - var info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['Monster'] ); - expect(info.text).toBe(''); - - desc = '{Object} cookie - {@type Monster}'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['Monster'] ); - expect(info.text).toBe(''); - - desc = '{Object} cookie - The cookie parameter. {@type Monster}'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['Monster'] ); - expect(info.text).toBe('The cookie parameter.'); - - desc = '{Object} cookie - The cookie parameter. {@type (Monster|Jar)}'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['Monster', 'Jar'] ); - expect(info.text).toBe('The cookie parameter.'); - - desc = '{Object} cookie - The cookie parameter. {@type (Monster|Jar)} Mmm, cookie.'; - info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['Monster', 'Jar'] ); - expect(info.text).toBe('The cookie parameter. Mmm, cookie.'); - }); - - describe('JSDoc-style type info', function() { - it('should parse JSDoc-style optional parameters', function() { - var name = '[qux]'; - var desc = 'The qux parameter.'; - var info = jsdoc.tag.type.parse( buildText(null, name, desc), true, false ); - expect(info.name).toBe('qux'); - expect(info.text).toBe(desc); - expect(info.optional).toBe(true); - - name = '[ qux ]'; - info = jsdoc.tag.type.parse( buildText(null, name, desc), true, false ); - expect(info.name).toBe('qux'); - expect(info.text).toBe(desc); - expect(info.optional).toBe(true); - - name = '[qux=hooray]'; - info = jsdoc.tag.type.parse( buildText(null, name, desc), true, false ); - expect(info.name).toBe('qux'); - expect(info.text).toBe(desc); - expect(info.optional).toBe(true); - expect(info.defaultvalue).toBe('hooray'); - - name = '[ qux = hooray ]'; - info = jsdoc.tag.type.parse( buildText(null, name, desc), true, false ); - expect(info.name).toBe('qux'); - expect(info.text).toBe(desc); - expect(info.optional).toBe(true); - expect(info.defaultvalue).toBe('hooray'); - }); - }); - - // TODO: add more tests related to how JSDoc mangles the Catharsis parse results - describe('Closure Compiler-style type info', function() { - it('should recognize variable (repeatable) parameters', function() { - var desc = '{...string} foo - Foo.'; - var info = jsdoc.tag.type.parse(desc, true, true); - expect(info.type).toEqual( ['string'] ); - expect(info.variable).toBe(true); - }); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/validator.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tag/validator.js deleted file mode 100644 index ec42c4ab..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tag/validator.js +++ /dev/null @@ -1,96 +0,0 @@ -/*global afterEach: true, beforeEach: true, describe: true, env: true, expect: true, it: true, spyOn: true */ -describe('jsdoc/tag/validator', function() { - var validator = require('jsdoc/tag/validator'), - tag = require('jsdoc/tag'); - - it('should exist', function() { - expect(validator).toBeDefined(); - expect(typeof validator).toBe('object'); - }); - - it('should export a validate function', function() { - expect(validator.validate).toBeDefined(); - expect(typeof validator.validate).toBe('function'); - }); - - // Note: various Error classes are private so we just test whether *any* - // error was thrown, not against particular types (e.g. UnknownTagError). - describe('validate', function() { - var dictionary = require('jsdoc/tag/dictionary'), - lenient = !!env.opts.lenient, - allowUnknown = !!env.conf.tags.allowUnknownTags, - badTag = {title: 'lkjasdlkjfb'}, - meta = {filename: 'asdf.js', lineno: 1}, - goodTag = new tag.Tag('name', 'MyDocletName', meta), // mustHaveValue - goodTag2 = new tag.Tag('ignore', '', meta); // mustNotHaveValue - - function validateTag(tag) { - return function() { validator.validate(tag, dictionary.lookUp(tag.title), meta); }; - } - - beforeEach(function() { - spyOn(console, 'log'); - }); - - afterEach(function() { - env.opts.lenient = lenient; - env.conf.tags.allowUnknownTags = allowUnknown; - }); - - it("throws an error if the tag is not in the dictionary, conf.tags.allowUnknownTags is false and lenient is false", function() { - env.opts.lenient = false; - env.conf.tags.allowUnknownTags = false; - expect(validateTag(badTag)).toThrow(); - }); - - it("throws NO error if the tag is not in the dictionary, conf.tags.allowUnknownTags is false and lenient is true", function() { - env.opts.lenient = true; - env.conf.tags.allowUnknownTags = false; - expect(validateTag(badTag)).not.toThrow(); - }); - - it("doesn't throw an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is true, regardless of lenience", function() { - // if it doesn't throw an error with lenient false, then it won't throw it with lenient true (we have - // tested lenient already in util/error.js) - env.opts.lenient = false; - env.conf.tags.allowUnknownTags = true; - expect(validateTag(badTag)).not.toThrow(); - }); - - it("throws no error for valid tags", function() { - env.opts.lenient = false; - expect(validateTag(goodTag)).not.toThrow(); - expect(validateTag(goodTag2)).not.toThrow(); - }); - - it("throws an error if the tag has no text but .mustHaveValue is true and lenient is false, or none if it's true", function() { - // the name tag has .mustHaveValue. - var oldText = goodTag.text; - delete goodTag.text; - - env.opts.lenient = false; - expect(validateTag(goodTag)).toThrow(); - - env.opts.lenient = true; - expect(validateTag(goodTag)).not.toThrow(); - - goodTag.text = oldText; - }); - - it("throws an error if the tag has text but .mustNotHaveValue is true and lenient is false, or none if it's true", function() { - var oldVal = goodTag2.mustNotHaveValue, - text = goodTag2.text; - goodTag2.mustNotHaveValue = true; - goodTag2.text = goodTag2.text || 'asdf'; - - env.opts.lenient = false; - expect(validateTag(goodTag2)).toThrow(); - - env.opts.lenient = true; - expect(validateTag(goodTag2)).not.toThrow(); - - goodTag2.mustNotHaveValue = oldVal; - goodTag2.text = oldVal; - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tutorial.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tutorial.js deleted file mode 100644 index caba78e6..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tutorial.js +++ /dev/null @@ -1,226 +0,0 @@ -/*global describe: true, env: true, it: true */ -describe("jsdoc/tutorial", function() { - var tutorial = require('jsdoc/tutorial'), - name = "tuteID", - content = "Tutorial content blah blah blah & <", - tute = new tutorial.Tutorial(name, content, tutorial.TYPES.NOTAVALUE), - par = new tutorial.Tutorial('parent', "# This is the parent tutorial's content & stuff A_B X_Y", - tutorial.TYPES.MARKDOWN), - par2 = new tutorial.Tutorial('parent2', "

      This is the second parent tutorial

      ", - tutorial.TYPES.HTML); - - - it("module should exist", function() { - expect(tutorial).toBeDefined(); - expect(typeof tutorial).toBe("object"); - }); - - it("should export a Tutorial function", function() { - expect(tutorial.Tutorial).toBeDefined(); - expect(typeof tutorial.Tutorial).toBe("function"); - }); - - it("should export a TYPES object", function() { - expect(tutorial.TYPES).toBeDefined(); - expect(typeof tutorial.TYPES).toBe("object"); - }); - - describe("tutorial.TYPES", function() { - it("should have a HTML property", function() { - expect(tutorial.TYPES.HTML).toBeDefined(); - }); - - it("should have a MARKDOWN property", function() { - expect(tutorial.TYPES.MARKDOWN).toBeDefined(); - }); - }); - - describe("Tutorial", function() { - it("should have 'setParent' function", function() { - expect(tutorial.Tutorial.prototype.setParent).toBeDefined(); - expect(typeof tutorial.Tutorial.prototype.setParent).toBe("function"); - }); - - it("should have 'removeChild' function", function() { - expect(tutorial.Tutorial.prototype.removeChild).toBeDefined(); - expect(typeof tutorial.Tutorial.prototype.removeChild).toBe("function"); - }); - - it("should have 'addChild' function", function() { - expect(tutorial.Tutorial.prototype.addChild).toBeDefined(); - expect(typeof tutorial.Tutorial.prototype.addChild).toBe("function"); - }); - - it("should have 'parse' function", function() { - expect(tutorial.Tutorial.prototype.parse).toBeDefined(); - expect(typeof tutorial.Tutorial.prototype.parse).toBe("function"); - }); - - it("should have a 'name' property", function() { - expect(tute.name).toBeDefined(); - expect(typeof tute.name).toBe("string"); - expect(tute.name).toBe(name); - }); - - it("should have a 'title' property, by default set to to the tute's name", function() { - expect(tute.title).toBeDefined(); - expect(typeof tute.title).toBe("string"); - expect(tute.title).toBe(name); - // Testing of overriding a tutorial's title in its JSON file is - // covered in tutorial/resolver.js tests. - }); - - it("should have a 'content' property set to the tutorial's content", function() { - expect(tute.content).toBeDefined(); - expect(typeof tute.content).toBe("string"); - expect(tute.content).toBe(content); - }); - - it("should have a 'type' property set to the tutorial's type", function() { - expect(par.type).toBeDefined(); - expect(typeof par.type).toBe(typeof tutorial.TYPES.MARKDOWN); - expect(par.type).toBe(tutorial.TYPES.MARKDOWN); - }); - - it("should have a 'parent' property, initially null", function() { - expect(tute.parent).toBeDefined(); - expect(tute.parent).toBe(null); - }); - - it("should have a 'children' property, an empty array", function() { - expect(tute.children).toBeDefined(); - expect(Array.isArray(tute.children)).toBe(true); - expect(tute.children.length).toBe(0); - }); - - describe("setParent", function() { - it("adding a parent sets the child's 'parent' property", function() { - tute.setParent(par); - expect(tute.parent).toBe(par); - }); - - it("adding a parent adds the child to the parent's 'children' property", function() { - expect(par.children).toContain(tute); - }); - - it("re-parenting removes the child from the previous parent", function() { - tute.setParent(par2); - - expect(tute.parent).toBe(par2); - expect(par2.children).toContain(tute); - expect(par.children).not.toContain(tute); - }); - - it("calling setParent with a null parent unsets the child's parent and removes the child from its previous parent", function() { - expect(par2.children).toContain(tute); - tute.setParent(null); - - expect(tute.parent).toBe(null); - expect(par2.children).not.toContain(tute); - }); - }); - - describe("addChild", function() { - it("adding a child tutorial adds the child to the parent's 'children' property", function() { - tute.setParent(null); - var n = par.children.length; - - par.addChild(tute); - - expect(par.children.length).toBe(n + 1); - expect(par.children).toContain(tute); - }); - - it("adding a child tutorial sets the child's parent to to the parent tutorial", function() { - expect(tute.parent).toBe(par); - }); - - it("adding a child tutorial removes the child from its old parent", function() { - // tue is currently owned by par; we reparent it to par2 - expect(tute.parent).toBe(par); - par2.addChild(tute); - - expect(tute.parent).toBe(par2); - expect(par.children).not.toContain(tute); - expect(par2.children).toContain(tute); - }); - }); - - describe("removeChild", function() { - function removeChild() { - par2.removeChild(par); - } - - it("removing a tutorial that is not a child silently passes", function() { - var n = par2.children.length; - expect(removeChild).not.toThrow(); - expect(par2.children.length).toBe(n); - }); - - it("removing a child removes the child from the parent's 'children' property", function() { - tute.setParent(par2); - expect(par2.children.length).toBe(1); - - par2.removeChild(tute); - - expect(par2.children).not.toContain(tute); - expect(par2.children.length).toBe(0); - }); - - it("removing a child unsets the child's 'parent' property", function() { - expect(tute.parent).toBe(null); - }); - }); - - describe("various inheritance tests with addChild, setParent and removeChild", function() { - it("parenting and unparenting via addChild, setParent and removeChild makes sure inheritance is set accordingly", function() { - // unparent everything. - tute.setParent(null); - par.setParent(null); - par2.setParent(null); - - // let tute belong to par - tute.setParent(par); - expect(tute.parent).toBe(par); - expect(par2.children.length).toBe(0); - expect(par.children.length).toBe(1); - expect(par.children[0]).toBe(tute); - - // addChild tute to par2. its parent should now be par2, and - // it can't be the child of two parents - par2.addChild(tute); - expect(tute.parent).toBe(par2); - expect(par.children.length).toBe(0); - expect(par2.children.length).toBe(1); - expect(par2.children[0]).toBe(tute); - - // removeChild tute from par2. tute should now be unparented. - par2.removeChild(tute); - expect(tute.parent).toBe(null); - expect(par.children.length).toBe(0); - expect(par2.children.length).toBe(0); - }); - }); - - describe("parse", function() { - it("Tutorials with HTML type return content as-is", function() { - expect(par2.parse()).toBe("

      This is the second parent tutorial

      "); - }); - - it("Tutorials with MARKDOWN type go through the markdown parser, respecting configuration options", function() { - var old = env.conf.markdown; - env.conf.markdown = {parser: 'evilstreak'}; - expect(par.parse()).toBe("

      This is the parent tutorial's content & stuff AB XY

      "); - - env.conf.markdown = {parser: 'marked'}; - expect(par.parse()).toBe("

      This is the parent tutorial's content & stuff A_B X_Y

      "); - - env.conf.markdown = old; - }); - - it("Tutorials with unrecognised type are returned as-is", function() { - expect(tute.parse()).toBe(content); - }); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/tutorial/resolver.js b/rsc/scripts/jsdoc/test/specs/jsdoc/tutorial/resolver.js deleted file mode 100644 index 5a4eef13..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/tutorial/resolver.js +++ /dev/null @@ -1,231 +0,0 @@ -/*global afterEach: true, describe: true, env: true, expect: true, it: true */ -describe("jsdoc/tutorial/resolver", function() { - var resolver = require('jsdoc/tutorial/resolver'), - tutorial = require('jsdoc/tutorial'), - lenient = !!env.opts.lenient, - log = eval(console.log); - - /*jshint evil: true */ - it("should exist", function() { - expect(resolver).toBeDefined(); - expect(typeof resolver).toBe('object'); - }); - - it("should export a 'addTutorial' function", function() { - expect(resolver.addTutorial).toBeDefined(); - expect(typeof resolver.addTutorial).toBe("function"); - }); - - it("should export a 'load' function", function() { - expect(resolver.load).toBeDefined(); - expect(typeof resolver.load).toBe("function"); - }); - - it("should export a 'resolve' function", function() { - expect(resolver.resolve).toBeDefined(); - expect(typeof resolver.resolve).toBe("function"); - }); - - it("should export a 'root' tutorial", function() { - expect(resolver.root).toBeDefined(); - expect(resolver.root instanceof tutorial.Tutorial).toBe(true); - }); - - it("exported 'root' tutorial should export a 'getByName' function", function() { - expect(resolver.root.getByName).toBeDefined(); - expect(typeof resolver.root.getByName).toBe("function"); - }); - - // note: every time we addTutorial or run the resolver, we are *adding* - // to the root tutorial. - - // addTutorial - var tute = new tutorial.Tutorial('myTutorial', '', tutorial.TYPES.HTML); - resolver.addTutorial(tute); - describe("addTutorial", function() { - - it("should add a default parent of the root tutorial", function() { - expect(tute.parent).toBe(resolver.root); - }); - - it("should be added to the root tutorial as a child", function() { - expect(resolver.root.children).toContain(tute); - }); - }); - - // root.getByName - describe("root.getByName", function() { - it("can retrieve tutorials by name", function() { - expect(resolver.root.getByName('myTutorial')).toBe(tute); - }); - - it("returns nothing for non-existent tutorials", function() { - expect(resolver.root.getByName('asdf')).toBeFalsy(); - }); - - it("is careful with tutorials whose names are reserved keywords in JS", function() { - expect(resolver.root.getByName('prototype')).toBeFalsy(); - }); - }); - - // load - resolver.load(__dirname + "/test/tutorials/tutorials"); - var childNames = resolver.root.children.map(function (t) { return t.name; }), - test = resolver.root.getByName('test'), - test2 = resolver.root.getByName('test2'), - test3 = resolver.root.getByName('test3'), - test4 = resolver.root.getByName('test4'), - test6 = resolver.root.getByName('test6'), - constr = resolver.root.getByName('constructor'); - - describe("load", function() { - - it("all tutorials are added, initially as top-level tutorials", function() { - // check they were added - expect(test).toBeDefined(); - expect(test2).toBeDefined(); - expect(test3).toBeDefined(); - expect(test4).toBeDefined(); - expect(test6).toBeDefined(); - expect(constr).toBeDefined(); - // check they are top-level in resolver.root - expect(childNames).toContain('test'); - expect(childNames).toContain('test2'); - expect(childNames).toContain('test3'); - expect(childNames).toContain('test4'); - expect(childNames).toContain('test6'); - }); - - it("tutorials with names equal to reserved keywords in JS still function as expected", function() { - expect(constr instanceof tutorial.Tutorial).toBe(true); - }); - - it("non-tutorials are skipped", function() { - expect(resolver.root.getByName('multiple')).toBeFalsy(); - expect(resolver.root.getByName('test5')).toBeFalsy(); - }); - - it("tutorial types are determined correctly", function() { - // test.html, test2.markdown, test3.html, test4.md, test6.xml - expect(test.type).toBe(tutorial.TYPES.HTML); - expect(test2.type).toBe(tutorial.TYPES.MARKDOWN); - expect(test3.type).toBe(tutorial.TYPES.HTML); - expect(test4.type).toBe(tutorial.TYPES.MARKDOWN); - expect(test6.type).toBe(tutorial.TYPES.HTML); - expect(constr.type).toBe(tutorial.TYPES.MARKDOWN); - }); - - }); - - // resolve - // myTutorial - // constructor - // test - // |- test2 - // |- test6 - // |- test3 - // |- test4 - describe("resolve", function() { - resolver.resolve(); - it("hierarchy is resolved properly no matter how the children property is defined", function() { - // root has child 'test' - expect(resolver.root.children.length).toBe(3); - expect(resolver.root.children).toContain(test); - expect(resolver.root.children).toContain(constr); - expect(test.parent).toBe(resolver.root); - expect(constr.parent).toBe(resolver.root); - - // test has child 'test2' - expect(test.children.length).toBe(1); - expect(test.children).toContain(test2); - expect(test2.parent).toBe(test); - - // test2 has children test3, test6 - expect(test2.children.length).toBe(2); - expect(test2.children).toContain(test3); - expect(test2.children).toContain(test6); - expect(test3.parent).toBe(test2); - expect(test6.parent).toBe(test2); - - // test3 has child test4 - expect(test3.children.length).toBe(1); - expect(test3.children).toContain(test4); - expect(test4.parent).toBe(test3); - }); - - it("tutorials without configuration files have titles matching filenames", function() { - // test6.xml didn't have a metadata - expect(test6.title).toBe('test6'); - }); - - it("tutorials with configuration files have titles as specified in configuration", function() { - // test.json had info for just test.json - expect(test.title).toBe("Test tutorial"); - }); - - it("multiple tutorials can appear in a configuration file", function() { - expect(test2.title).toBe("Test 2"); - expect(test3.title).toBe("Test 3"); - expect(test4.title).toBe("Test 4"); - }); - }); - - // error reporting. - describe("Error reporting", function() { - // Tests for error reporting. - function missingTutorial() { - resolver.load(__dirname + "/test/tutorials/incomplete"); - resolver.resolve(); - } - function duplicateNamedTutorials() { - // can't add a tutorial if another with its name has already been added - resolver.addTutorial(tute); - } - function duplicateDefinedTutorials() { - // can't have a tutorial's metadata defined twice in .json files - resolver.load(__dirname + "/test/tutorials/duplicateDefined"); - resolver.resolve(); - } - - afterEach(function() { - env.opts.lenient = lenient; - console.log = log; - }); - - it("throws an exception for missing tutorials if the lenient option is not enabled", function() { - env.opts.lenient = false; - - expect(missingTutorial).toThrow(); - }); - - it("doesn't throw an exception for missing tutorials if the lenient option is enabled", function() { - console.log = function() {}; - env.opts.lenient = true; - - expect(missingTutorial).not.toThrow(); - }); - - it("throws an exception for duplicate-named tutorials (e.g. test.md, test.html) if the lenient option is not enabled", function() { - env.opts.lenient = false; - expect(duplicateNamedTutorials).toThrow(); - }); - - it("doesn't throw an exception for duplicate-named tutorials (e.g. test.md, test.html) if the lenient option is not enabled", function() { - console.log = function() {}; - env.opts.lenient = true; - expect(duplicateNamedTutorials).not.toThrow(); - }); - - it("throws an exception for tutorials defined twice in .jsons if the lenient option is not enabled", function() { - env.opts.lenient = false; - expect(duplicateDefinedTutorials).toThrow(); - }); - - it("doesn't throw an exception for tutorials defined twice in .jsons if the lenient option is not enabled", function() { - console.log = function() {}; - env.opts.lenient = true; - expect(duplicateDefinedTutorials).not.toThrow(); - }); - }); - -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/doop.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/doop.js deleted file mode 100644 index 217303de..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/doop.js +++ /dev/null @@ -1,73 +0,0 @@ -/*global describe: true, it: true */ -describe('jsdoc/util/doop', function() { - var doop = require('jsdoc/util/doop'); - - it('should exist', function() { - expect(doop).toBeDefined(); - expect(typeof doop).toBe('object'); - }); - - it('should export a doop function', function() { - expect(doop.doop).toBeDefined(); - expect(typeof doop.doop).toBe('function'); - }); - - // deep-clones a simple object. - describe('doop', function() { - it("should return the input object if it's simple (boolan, string etc) or a function", function() { - // .toBe uses === to test. - - // test a number... - expect(doop.doop(3)).toBe(3); - // test a string... - expect(doop.doop('asdf')).toBe('asdf'); - // test a boolean... - expect(doop.doop(true)).toBe(true); - // test a function... - var f = function () {}; - expect(doop.doop(f)).toBe(f); - }); - - it("should return a clone of an array", function() { - var inp = [1,2,3], - out = doop.doop(inp); - // toEqual is a comparison on properties; toBe is === comparison. - expect(inp).toEqual(out); - expect(inp).not.toBe(out); - }); - - it("should return a clone of an object", function() { - var inp = {a:1, b:2, 'asdf-fdsa': 3}; - out = doop.doop(inp); - // toEqual is a comparison on properties; toBe is === comparison. - expect(inp).toEqual(out); - expect(inp).not.toBe(out); - }); - - // checks that a === b if it's not an object or array (or it's af function); - // otherwise recurses down into keys and compares them. - function compareForEquality(a, b) { - if (a instanceof Object && a.constructor != Function) { - // if it's an object and not a function, it should clone. - var keys = Object.keys(a); - expect(Object.keys(a)).toEqual(Object.keys(b)); - for (var i = 0; i < keys.length; ++i) { - compareForEquality(a[keys[i]], b[keys[i]]); - } - } else { - // otherwise, it should be exactly equal. - expect(a).toBe(b); - } - } - - it("should clone recursively", function() { - var inp = {a:1, b:2, 'asdf-fdsa': {a: 'fdsa', b: [1,2,3]}}; - out = doop.doop(inp); - // toEqual is a comparison on properties; toBe is === comparison. - expect(inp).toEqual(out); - expect(inp).not.toBe(out); - // double-check - compareForEquality(inp, out); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/dumper.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/dumper.js deleted file mode 100644 index 25e48141..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/dumper.js +++ /dev/null @@ -1,103 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("common/dumper", function() { - var common = {dumper: require('jsdoc/util/dumper')}; - - it("should exist", function() { - expect(common.dumper).toBeDefined(); - expect(typeof common.dumper).toEqual("object"); - }); - - it("should export a 'dump' function", function() { - expect(common.dumper.dump).toBeDefined(); - expect(typeof common.dumper.dump).toEqual("function"); - }); - - it("can dump string values", function() { - expect(common.dumper.dump('hello')).toEqual('"hello"'); - }); - - it("escapes double quotes in string values", function() { - expect(common.dumper.dump('hello "world"')).toEqual('"hello \\"world\\""', 'Double quotes should be escaped.'); - }); - - it("escapes newlines in string values", function() { - expect(common.dumper.dump('hello\nworld')).toEqual('"hello\\nworld"', 'Newlines should be escaped.'); - }); - - it("can dump number values", function() { - expect(common.dumper.dump(1)).toEqual('1'); - expect(common.dumper.dump(0.1)).toEqual('0.1'); - }); - - it("can dump boolean values", function() { - expect(common.dumper.dump(true)).toEqual('true'); - expect(common.dumper.dump(false)).toEqual('false'); - }); - - it("can dump null values", function() { - expect(common.dumper.dump(null)).toEqual('null'); - }); - - it("can dump undefined values", function() { - expect(common.dumper.dump(undefined)).toEqual('"undefined"'); - }); - - it("can dump regex values", function() { - expect(common.dumper.dump(/^[Ff]oo$/gi)).toEqual('""'); - }); - - it("can dump date values", function() { - expect(common.dumper.dump(new Date('January 1, 1901 GMT'))) - .toEqual('""'); - }); - - it("can dump function values", function() { - expect(common.dumper.dump(function myFunc(){})).toEqual('""'); - expect(common.dumper.dump(function(){})).toEqual('""'); - }); - - it("can dump array values", function() { - var actual = common.dumper.dump(["hello", "world"]), - expected = '[\n "hello",\n "world"\n]'; - - expect(actual).toEqual(expected); - }); - - it("can dump simple object values", function() { - var actual = common.dumper.dump({hello: "world"}), - expected = '{\n "hello": "world"\n}'; - - expect(actual).toEqual(expected); - }); - - it("can dump constructed instance values, not displaying prototype members", function() { - function Foo(name){ this.name = name; } - Foo.prototype.sayHello = function(){}; - - var actual = common.dumper.dump(new Foo('hello')), - expected = '{\n "name": "hello"\n}'; - - expect(actual).toEqual(expected); - }); - - it("can dump complex mixed values", function() { - function Foo(){} - - var actual = common.dumper.dump( - [undefined, null, new Foo(), 1, true, 'hello\n"world', new Error('oops'), /foo/gi, new Date('December 26, 2010 GMT'), {f: function myFunc(){}, o: {a:1}}] - ), - expected = '[\n "undefined",\n null,\n {},\n 1,\n true,\n "hello\\n\\"world",\n {\n "message": "oops"\n },\n "",\n "",\n {\n "f": "",\n "o": {\n "a": 1\n }\n }\n]'; - - expect(actual).toEqual(expected); - }); - - it("doesn't crash on circular references", function() { - var a = {}; - a.b = a; - - var actual = common.dumper.dump(a), - expected = '{\n "b": ""\n}'; - - expect(actual).toEqual(expected); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/error.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/error.js deleted file mode 100644 index 4b77e789..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/error.js +++ /dev/null @@ -1,53 +0,0 @@ -/*global describe: true, env: true, it: true */ -describe("jsdoc/util/error", function() { - var error = require('jsdoc/util/error'), - handle = error.handle; - - it("should exist", function() { - expect(error).toBeDefined(); - expect(typeof error).toEqual("object"); - }); - - it("should export a 'handle' function", function() { - expect(handle).toBeDefined(); - expect(typeof handle).toEqual("function"); - }); - - describe("handle", function() { - /*jshint evil: true */ - var lenient = !!env.opts.lenient; - - function handleError() { - handle( new Error("foo") ); - } - - function handleObject() { - handle( { foo: "bar", baz: "qux"} ); - } - - afterEach(function() { - env.opts.lenient = lenient; - }); - - it("should re-throw errors by default", function() { - expect(handleError).toThrow(); - }); - - it("should re-throw errors if lenient mode is not enabled", function() { - env.opts.lenient = false; - - expect(handleError).toThrow(); - }); - - it("should not re-throw errors if lenient mode is enabled", function() { - env.opts.lenient = true; - spyOn(console, 'log'); - - expect(handleError).not.toThrow(); - }); - - it("should still work if the 'e' param is not an instanceof Error", function() { - expect(handleObject).toThrow(); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/include.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/include.js deleted file mode 100644 index 25e28323..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/include.js +++ /dev/null @@ -1,36 +0,0 @@ -/*global afterEach: true, beforeEach: true, describe: true, env: true, expect: true, it: true, -__globalForIncludeTest__: true */ -describe("jsdoc/util/include", function() { - var include = require('jsdoc/util/include'); - var myGlobal = require('jsdoc/util/global'); - var path = require('path'); - - var fixturePath = 'test/fixtures/include.js'; - - beforeEach(function() { - myGlobal.__globalForIncludeTest__ = 0; - }); - - afterEach(function() { - myGlobal.__globalForIncludeTest__ = undefined; - }); - - it("should exist", function() { - expect(include).toBeDefined(); - expect(typeof include).toEqual('function'); - }); - - it("should work with a path relative to __dirname", function() { - include(fixturePath); - expect(__globalForIncludeTest__).toEqual(1); - }); - - // Note: This test also verifies that include() executes the file each time it's passed in, - // rather than executing it once and caching the result, as with require(). - it("should work with an absolute path", function() { - var _path = path.resolve(__dirname, fixturePath); - - include(_path); - expect(__globalForIncludeTest__).toEqual(1); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/markdown.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/markdown.js deleted file mode 100644 index fad1222b..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/markdown.js +++ /dev/null @@ -1,96 +0,0 @@ -/*global describe: true, env: true, expect: true, it: true, xit: true */ -describe('jsdoc/util/markdown', function() { - var markdown = require('jsdoc/util/markdown'); - - it('should exist', function() { - expect(markdown).toBeDefined(); - expect(typeof markdown).toEqual('object'); - }); - - it('should export a "getParser" function', function() { - expect(markdown.getParser).toBeDefined(); - expect(typeof markdown.getParser).toEqual('function'); - }); - - describe('getParser', function() { - // couple of convenience functions letting me set conf variables and restore - // them back to the originals later. - function setMarkdownConf(hash) { - if (!env.conf.markdown) { - env.conf.markdown = {}; - } - var keys = Object.keys(hash); - var storage = {}; - for (var i = 0; i < keys.length; ++i) { - storage[keys[i]] = env.conf.markdown[keys[i]]; - // works because hash[key] is a scalar not an array/object - env.conf.markdown[keys[i]] = hash[keys[i]]; - } - return storage; - } - - function restoreMarkdownConf(storage) { - var keys = Object.keys(storage); - for (var i = 0; i < keys.length; ++i) { - env.conf.markdown[keys[i]] = storage[keys[i]]; - } - if (keys.length === 0) { - delete env.conf.markdown; - } - } - - it('should retrieve a function when called with default settings', function() { - var storage = setMarkdownConf({parser: 'evilstreak'}); - - var parser = markdown.getParser(); - expect(typeof parser).toEqual('function'); - - setMarkdownConf({parser: 'marked'}); - parser = markdown.getParser(); - expect(typeof parser).toEqual('function'); - - restoreMarkdownConf(storage); - }); - - it('should use the evilstreak parser when requested', function() { - var storage = setMarkdownConf({parser: 'evilstreak'}); - var parser = markdown.getParser(); - expect(parser._parser).toEqual('markdown'); - restoreMarkdownConf(storage); - }); - - it('should use the marked parser when requested', function() { - var storage = setMarkdownConf({parser: 'marked'}); - var parser = markdown.getParser(); - expect(parser._parser).toEqual('marked'); - restoreMarkdownConf(storage); - }); - - it('should use the marked parser when GFM is requested', function() { - var storage = setMarkdownConf({parser: 'gfm'}); - var parser = markdown.getParser(); - expect(parser._parser).toEqual('marked'); - restoreMarkdownConf(storage); - }); - - it('should not apply formatting to inline tags when the evilstreak parser is enabled', function() { - var storage = setMarkdownConf({parser: 'evilstreak'}); - var parser = markdown.getParser(); - - // get the evilstreak parser and do the test - expect(parser('{@link MyClass#_x} and {@link MyClass#_y}')).toEqual( - '

      {@link MyClass#_x} and {@link MyClass#_y}

      '); - restoreMarkdownConf(storage); - }); - - it('should not apply formatting to inline tags when the marked parser is enabled', function() { - var storage = setMarkdownConf({parser: 'marked'}); - var parser = markdown.getParser(); - - // get the marked parser and do the test - expect(parser('{@link MyClass#_x} and {@link MyClass#_y}')).toEqual( - '

      {@link MyClass#_x} and {@link MyClass#_y}

      '); - restoreMarkdownConf(storage); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/templateHelper.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/templateHelper.js deleted file mode 100644 index 3e8e8cdb..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/templateHelper.js +++ /dev/null @@ -1,1353 +0,0 @@ -/*global afterEach: true, beforeEach: true, describe: true, expect: true, env: true, it: true, -jasmine: true, spyOn: true, xdescribe: true */ -var hasOwnProp = Object.prototype.hasOwnProperty; - -describe("jsdoc/util/templateHelper", function() { - var helper = require('jsdoc/util/templateHelper'), - doclet = require('jsdoc/doclet'), - resolver = require('jsdoc/tutorial/resolver'), - taffy = require('taffydb').taffy; - helper.registerLink('test', 'path/to/test.html'); - - it("should exist", function() { - expect(helper).toBeDefined(); - expect(typeof helper).toBe('object'); - }); - - it("should export a 'setTutorials' function", function() { - expect(helper.setTutorials).toBeDefined(); - expect(typeof helper.setTutorials).toBe("function"); - }); - - it("should export a 'globalName' property", function() { - expect(helper.globalName).toBeDefined(); - expect(typeof helper.globalName).toBe("string"); - }); - - it("should export a 'fileExtension' property", function() { - expect(helper.fileExtension).toBeDefined(); - expect(typeof helper.fileExtension).toBe("string"); - }); - - it("should export a 'scopeToPunc' property", function() { - expect(helper.scopeToPunc).toBeDefined(); - expect(typeof helper.scopeToPunc).toBe("object"); - }); - - it("should export a 'getUniqueFilename' function", function() { - expect(helper.getUniqueFilename).toBeDefined(); - expect(typeof helper.getUniqueFilename).toBe("function"); - }); - - it("should export a 'longnameToUrl' property", function() { - expect(helper.longnameToUrl).toBeDefined(); - expect(typeof helper.longnameToUrl).toBe("object"); - }); - - it("should export a 'linkto' function", function() { - expect(helper.linkto).toBeDefined(); - expect(typeof helper.linkto).toBe("function"); - }); - - it("should export an 'htmlsafe' function", function() { - expect(helper.htmlsafe).toBeDefined(); - expect(typeof helper.htmlsafe).toBe("function"); - }); - - it("should export a 'find' function", function() { - expect(helper.find).toBeDefined(); - expect(typeof helper.find).toBe("function"); - }); - - it("should export a 'getMembers' function", function() { - expect(helper.getMembers).toBeDefined(); - expect(typeof helper.getMembers).toBe("function"); - }); - - it("should export a 'getAttribs' function", function() { - expect(helper.getAttribs).toBeDefined(); - expect(typeof helper.getAttribs).toBe("function"); - }); - - it("should export a 'getSignatureTypes' function", function() { - expect(helper.getSignatureTypes).toBeDefined(); - expect(typeof helper.getSignatureTypes).toBe("function"); - }); - - it("should export a 'getSignatureParams' function", function() { - expect(helper.getSignatureParams).toBeDefined(); - expect(typeof helper.getSignatureParams).toBe("function"); - }); - - it("should export a 'getSignatureReturns' function", function() { - expect(helper.getSignatureReturns).toBeDefined(); - expect(typeof helper.getSignatureReturns).toBe("function"); - }); - - it("should export a 'getAncestorLinks' function", function() { - expect(helper.getAncestorLinks).toBeDefined(); - expect(typeof helper.getAncestorLinks).toBe("function"); - }); - - it("should export a 'addEventListeners' function", function() { - expect(helper.addEventListeners).toBeDefined(); - expect(typeof helper.addEventListeners).toBe("function"); - }); - - it("should export a 'prune' function", function() { - expect(helper.prune).toBeDefined(); - expect(typeof helper.prune).toBe("function"); - }); - - it("should export a 'registerLink' function", function() { - expect(helper.registerLink).toBeDefined(); - expect(typeof helper.registerLink).toBe("function"); - }); - - it("should export a 'tutorialToUrl' function", function() { - expect(helper.tutorialToUrl).toBeDefined(); - expect(typeof helper.tutorialToUrl).toBe("function"); - }); - - it("should export a 'toTutorial' function", function() { - expect(helper.toTutorial).toBeDefined(); - expect(typeof helper.toTutorial).toBe("function"); - }); - - it("should export a 'resolveLinks' function", function() { - expect(helper.resolveLinks).toBeDefined(); - expect(typeof helper.resolveLinks).toBe("function"); - }); - - it("should export a 'resolveAuthorLinks' function", function() { - expect(helper.resolveAuthorLinks).toBeDefined(); - expect(typeof helper.resolveAuthorLinks).toBe("function"); - }); - - it("should export a 'createLink' function", function() { - expect(helper.createLink).toBeDefined(); - expect(typeof helper.createLink).toBe("function"); - }); - - - describe("setTutorials", function() { - // used in tutorialToUrl, toTutorial. - it("setting tutorials to null causes all tutorial lookups to fail", function() { - // bit of a dodgy test but the best I can manage. setTutorials doesn't do much. - helper.setTutorials(null); - // should throw error: no 'getByName' in tutorials. - expect(function () { return helper.tutorialToUrl('asdf'); }).toThrow('Cannot call method "getByName" of null'); - }); - - it("setting tutorials to the root tutorial object lets lookups work", function() { - var lenient = !!env.opts.lenient; - spyOn(console, 'log'); - - // tutorial doesn't exist, we want to muffle that error - env.opts.lenient = true; - - helper.setTutorials(resolver.root); - spyOn(resolver.root, 'getByName'); - helper.tutorialToUrl('asdf'); - expect(resolver.root.getByName).toHaveBeenCalled(); - - env.opts.lenient = lenient; - }); - }); - - describe("globalName", function() { - it("should equal 'global'", function() { - expect(helper.globalName).toBe('global'); - }); - }); - - describe("fileExtension", function() { - it("should equal '.html'", function() { - expect(helper.fileExtension).toBe('.html'); - }); - }); - - describe("scopeToPunc", function() { - it("should map 'static' to '.', 'inner', to '~', 'instance' to '#'", function() { - expect(helper.scopeToPunc).toEqual({static: '.', inner: '~', instance: '#'}); - }); - }); - - describe("getUniqueFilename", function() { - // TODO: needs more tests for unusual values and things that get special treatment (such as - // inner members) - it('should convert a simple string into the string plus the default extension', function() { - var filename = helper.getUniqueFilename('BackusNaur'); - expect(filename).toBe('BackusNaur.html'); - }); - - it('should convert a string with slashes into the text following the last slash plus the default extension', function() { - var filename = helper.getUniqueFilename('tick/tock'); - expect(filename).toMatch(/^tock\.html$/); - }); - - it('should not return the same filename twice', function() { - var name = 'polymorphic'; - var filename1 = helper.getUniqueFilename(name); - var filename2 = helper.getUniqueFilename(name); - - expect(filename1).not.toBe(filename2); - }); - - it('should not consider the same name with different letter case to be unique', function() { - var camel = 'myJavaScriptIdentifier'; - var pascal = 'MyJavaScriptIdentifier'; - var filename1 = helper.getUniqueFilename(camel); - var filename2 = helper.getUniqueFilename(pascal); - - expect( filename1.toLowerCase() ).not.toBe( filename2.toLowerCase() ); - }); - - it('should remove variations from the longname before generating the filename', function() { - var filename = helper.getUniqueFilename('MyClass(foo, bar)'); - expect(filename).toBe('MyClass.html'); - }); - }); - - describe("longnameToUrl", function() { - it("is an object", function() { - expect(typeof helper.longnameToUrl).toBe('object'); - }); - - it("has an entry added into it by calling registerLink", function() { - helper.registerLink('MySymbol', 'asdf.html'); - expect(helper.longnameToUrl.MySymbol).toBeDefined(); - expect(helper.longnameToUrl.MySymbol).toBe('asdf.html'); - - delete helper.longnameToUrl.MySymbol; - }); - - it("adding an entry to it allows me to link with linkto", function() { - helper.longnameToUrl.foo2 = 'bar.html'; - expect(helper.linkto('foo2')).toBe('foo2'); - delete helper.longnameToUrl.foo2; - }); - }); - - describe("linkto", function() { - beforeEach(function() { - helper.longnameToUrl.linktoTest = 'test.html'; - helper.longnameToUrl.LinktoFakeClass = 'fakeclass.html'; - }); - - afterEach(function() { - delete helper.longnameToUrl.linktoTest; - delete helper.longnameToUrl.LinktoFakeClass; - }); - - it('returns the longname if only the longname is specified and has no URL', function() { - var link = helper.linkto('example'); - expect(link).toBe('example'); - }); - - it('returns the link text if only the link text is specified', function() { - var link = helper.linkto(null, 'link text'); - expect(link).toBe('link text'); - }); - - it('returns the link text if the longname does not have a URL, and both the longname and ' + - 'link text are specified', function() { - var link = helper.linkto('example', 'link text'); - expect(link).toBe('link text'); - }); - - it('uses the longname as the link text if no link text is provided', function() { - var link = helper.linkto('linktoTest'); - expect(link).toBe('linktoTest'); - }); - - it('uses the link text if it is specified', function() { - var link = helper.linkto('linktoTest', 'link text'); - expect(link).toBe('link text'); - }); - - it('includes a "class" attribute in the link if a class is specified', function() { - var link = helper.linkto('linktoTest', 'link text', 'myclass'); - expect(link).toBe('link text'); - }); - - it('is careful with longnames that are reserved words in JS', function() { - // we don't have a registered link for 'constructor' so it should return the text 'link text'. - var link = helper.linkto('constructor', 'link text'); - expect(typeof link).toBe('string'); - expect(link).toBe('link text'); - }); - - it('works correctly with type applications if only the longname is specified', function() { - var link = helper.linkto('Array.'); - expect(link).toBe('Array.<LinktoFakeClass>'); - }); - - it('works correctly with type applications if a class is not specified', function() { - var link = helper.linkto('Array.', 'link text'); - expect(link).toBe('Array.<LinktoFakeClass>'); - }); - - it('works correctly with type applications if a class is specified', function() { - var link = helper.linkto('Array.', 'link text', 'myclass'); - expect(link).toBe('Array.<LinktoFakeClass' + - '>'); - }); - - it('works correctly with type applications that include a type union', function() { - var link = helper.linkto('Array.<(linktoTest|LinktoFakeClass)>', 'link text'); - expect(link).toBe('Array.<(linktoTest|' + - 'LinktoFakeClass)>'); - }); - - it('returns a link when a URL is specified', function() { - var link = helper.linkto('http://example.com'); - expect(link).toBe('http://example.com'); - }); - - it('returns a link if a URL wrapped in angle brackets is specified', function() { - var link = helper.linkto(''); - expect(link).toBe('http://example.com'); - }); - - it('returns a link with link text if a URL and link text are specified', function() { - var link = helper.linkto('http://example.com', 'text'); - expect(link).toBe('text'); - }); - - it('returns a link with a fragment ID if a URL and fragment ID are specified', function() { - var link = helper.linkto('LinktoFakeClass', null, null, 'fragment'); - expect(link).toBe('LinktoFakeClass'); - }); - - it('returns the original text if an inline {@link} tag is specified', function() { - var link; - var text = '{@link Foo}'; - - function getLink() { - link = helper.linkto(text); - } - - // make sure we're not trying to parse the inline link as a type expression - expect(getLink).not.toThrow(); - // linkto doesn't process {@link} tags - expect(link).toBe(text); - }); - }); - - describe("htmlsafe", function() { - // turns < into < (doesn't do > or & etc...) - it('should convert all occurences of < to <', function() { - var inp = '

      Potentially dangerous.

      ', - out = helper.htmlsafe(inp); - expect(out).toBe('<h1>Potentially dangerous.</h1>'); - }); - }); - - describe("find", function() { - var array = [ - // match - { number: 2, A: true }, - // match - { number: 1, A: true, D: 'hello', Q: false }, - // match - { number: 3, A: 'maybe', squiggle: '?' }, - // no match (number not in spec) - { number: 4, A: true }, - // no match (missing top-level property) - { A: true } - ]; - var matches = array.slice(0, 3); - var spec = { number: [1, 2, 3], A: [true, 'maybe'] }; - - it('should find the requested items', function() { - expect( helper.find(taffy(array), spec) ).toEqual(matches); - }); - }); - - // we can't use toEqual() because TaffyDB adds its own stuff to the array it returns. - // instead, we make sure arrays a and b are the same length, and that each object in - // array b has all the properties of the corresponding object in array a - // used for getMembers and prune tests. - function compareObjectArrays(a, b) { - expect(a.length).toEqual(b.length); - - for (var i = 0, l = a.length; i < l; i++) { - for (var prop in a[i]) { - if ( hasOwnProp.call(a[i], prop) ) { - expect(b[i][prop]).toBeDefined(); - expect(a[i][prop]).toEqual(b[i][prop]); - } - } - } - } - describe("getMembers", function() { - // instead parse a file from fixtures and verify it? - var classes = [ - {kind: 'class'}, // global - {kind: 'class', memberof: 'SomeNamespace'}, // not global - ]; - var externals = [ - {kind: 'external'}, - ]; - var events = [ - {kind: 'event'}, - ]; - var mixins = [ - {kind: 'mixin'}, - ]; - var modules = [ - {kind: 'module'}, - ]; - var namespaces = [ - {kind: 'namespace'}, - ]; - var misc = [ - {kind: 'function'}, // global - {kind: 'member'}, // global - {kind: 'constant'}, // global - {kind: 'typedef'}, // global - {kind: 'constant', memberof: 'module:one/two'}, // not global - {kind: 'function', name: 'module:foo', longname: 'module:foo'} // not global - ]; - var array = classes.concat(externals.concat(events.concat(mixins.concat(modules.concat(namespaces.concat(misc)))))); - var data = taffy(array); - var members = helper.getMembers(data); - - // check the output object has properties as expected. - it("should have a 'classes' property", function() { - expect(members.classes).toBeDefined(); - }); - - it("should have a 'externals' property", function() { - expect(members.externals).toBeDefined(); - }); - - it("should have a 'events' property", function() { - expect(members.events).toBeDefined(); - }); - - it("should have a 'globals' property", function() { - expect(members.globals).toBeDefined(); - }); - - it("should have a 'mixins' property", function() { - expect(members.mixins).toBeDefined(); - }); - - it("should have a 'modules' property", function() { - expect(members.modules).toBeDefined(); - }); - - it("should have a 'namespaces' property", function() { - expect(members.namespaces).toBeDefined(); - }); - - // check that things were found properly. - it("classes are detected", function() { - compareObjectArrays(classes, members.classes); - }); - - it("externals are detected", function() { - compareObjectArrays(externals, members.externals); - }); - - it("events are detected", function() { - compareObjectArrays(events, members.events); - }); - - it("mixins are detected", function() { - compareObjectArrays(mixins, members.mixins); - }); - - it("modules are detected", function() { - compareObjectArrays(modules, members.modules); - }); - - it("namespaces are detected", function() { - compareObjectArrays(namespaces, members.namespaces); - }); - - it("globals are detected", function() { - compareObjectArrays(misc.slice(0, -2), members.globals); - }); - }); - - describe("getAttribs", function() { - var doc, attribs; - - it('should return an array of strings', function() { - doc = new doclet.Doclet('/** ljklajsdf */', {}); - attribs = helper.getAttribs(doc); - expect(Array.isArray(attribs)).toBe(true); - }); - - // tests is an object of test[doclet src] = - // if false, we expect attribs to either not contain anything in whatNotToContain, - // or be empty (if whatNotToContain was not provided). - function doTests(tests, whatNotToContain) { - for (var src in tests) { - if (tests.hasOwnProperty(src)) { - doc = new doclet.Doclet('/** ' + src + ' */', {}); - attribs = helper.getAttribs(doc); - if (tests[src]) { - expect(attribs).toContain(tests[src]); - } else { - if (whatNotToContain !== undefined) { - if (Array.isArray(whatNotToContain)) { - for (var i = 0; i < whatNotToContain.length; ++i) { - expect(attribs).not.toContain(whatNotToContain[i]); - } - } - } else { - expect(attribs.length).toBe(0); - } - } - } - } - } - - it('should detect if a doclet is virtual', function() { - var tests = { - 'My constant. \n @virtual': 'virtual', - 'asdf': false - }; - doTests(tests); - }); - - it("should detect if a doclet's access is not public", function() { - var tests = {'@private': 'private', - '@access private': 'private', - '@protected': 'protected', - '@access protected': 'protected', - '@public': false, - '@access public': false, - 'asdf': false - }; - doTests(tests); - }); - - it("should detect if a doclet's scope is inner or static AND it is a function or member or constant", function() { - var tests = { - // by default these are members - '@inner': 'inner', - '@instance': false, - '@global': false, - '@static': 'static', - '@name Asdf.fdsa': 'static', - '@name Outer~inner': 'inner', - '@name Fdsa#asdf': false, - '@name .log': false, - // some tests with functions and constants - '@const Asdf#FOO': false, - '@const Asdf\n@inner': 'inner', - '@function Asdf#myFunction': false, - '@function Fdsa.MyFunction': 'static', - '@function Fdsa': false, - // these are not functions or members or constants, they should not have their scope recorded. - '@namespace Fdsa\n@inner': false, - '@class asdf': false - }; - doTests(tests, ['inner', 'static', 'global', 'instance']); - }); - - it("should detect if a doclet is readonly (and its kind is 'member')", function() { - var tests = { - 'asdf\n @readonly': 'readonly', - 'asdf': false, - '@name Fdsa#foo\n@readonly': 'readonly', - // kind is not 'member'. - '@const asdf\n@readonly': false, - '@function asdf\n@readonly': false, - '@function Asdf#bar\n@readonly': false - }; - doTests(tests, 'readonly'); - }); - - it("should detect if the doclet is a for constant", function() { - var tests = { - 'Enum. @enum\n@constant': 'constant', - '@function Foo#BAR\n@const': 'constant', - '@const Asdf': 'constant' - }; - doTests(tests, 'constant'); - }); - - it("should detect multiple attributes", function() { - var doc = new doclet.Doclet('/** @const module:fdsa~FOO\n@readonly\n@private */', {}); - attribs = helper.getAttribs(doc); - expect(attribs).toContain('private'); - //expect(attribs).toContain('readonly'); // kind is 'constant' not 'member'. - expect(attribs).toContain('constant'); - expect(attribs).toContain('inner'); - }); - }); - - describe("getSignatureTypes", function() { - // returns links to allowed types for a doclet. - it("returns an empty array if the doclet has no specified type", function() { - var doc = new doclet.Doclet('/** @const ASDF */', {}), - types = helper.getSignatureTypes(doc); - - expect(Array.isArray(types)).toBe(true); - expect(types.length).toBe(0); - }); - - it("returns a string array of the doclet's types", function() { - var doc = new doclet.Doclet('/** @const {number|Array.} ASDF */', {}), - types = helper.getSignatureTypes(doc); - - expect(types.length).toBe(2); - expect(types).toContain('number'); - expect(types).toContain(helper.htmlsafe('Array.')); // should be HTML safe - }); - - it("creates links for types if relevant", function() { - // make some links. - helper.longnameToUrl.MyClass = 'MyClass.html'; - - var doc = new doclet.Doclet('/** @const {MyClass} ASDF */', {}), - types = helper.getSignatureTypes(doc); - expect(types.length).toBe(1); - expect(types).toContain('MyClass'); - - delete helper.longnameToUrl.MyClass; - }); - - it("uses the cssClass parameter for links if it is provided", function() { - // make some links. - helper.longnameToUrl.MyClass = 'MyClass.html'; - - var doc = new doclet.Doclet('/** @const {MyClass} ASDF */', {}), - types = helper.getSignatureTypes(doc, 'myCSSClass'); - expect(types.length).toBe(1); - expect(types).toContain('MyClass'); - - delete helper.longnameToUrl.MyClass; - }); - }); - - describe("getSignatureParams", function() { - // retrieves parameter names. - // if css class is provided, optional parameters are wrapped in a with that class. - it("returns an empty array if the doclet has no specified type", function() { - var doc = new doclet.Doclet('/** @function myFunction */', {}), - params = helper.getSignatureParams(doc); - expect(Array.isArray(params)).toBe(true); - expect(params.length).toBe(0); - }); - - it("returns a string array of the doclet's parameter names", function() { - var doc = new doclet.Doclet('/** @function myFunction\n @param {string} foo - asdf. */', {}), - params = helper.getSignatureParams(doc); - expect(params.length).toBe(1); - expect(params).toContain('foo'); - }); - - it("wraps optional parameters in if optClass is provided", function() { - var doc = new doclet.Doclet( - '/** @function myFunction\n' + - ' * @param {boolean} foo - explanation.\n' + - ' * @param {number} [bar=1] - another explanation.\n' + - ' * @param {string} [baz] - another explanation.\n' + - ' */', {}), - params = helper.getSignatureParams(doc, 'cssClass'); - - expect(params.length).toBe(3); - expect(params).toContain('foo'); - expect(params).toContain('bar'); - expect(params).toContain('baz'); - }); - - it("doesn't wrap optional parameters in if optClass is not provided", function() { - var doc = new doclet.Doclet( - '/** @function myFunction\n' + - ' * @param {boolean} foo - explanation.\n' + - ' * @param {number} [bar=1] - another explanation.\n' + - ' * @param {string} [baz] - another explanation.\n' + - ' */', {}), - params = helper.getSignatureParams(doc); - - expect(params.length).toBe(3); - expect(params).toContain('foo'); - expect(params).toContain('bar'); - expect(params).toContain('baz'); - }); - }); - - describe("getSignatureReturns", function() { - // retrieves links to types that the member can return. - - it("returns a value with correctly escaped HTML", function() { - var mockDoclet = { - returns: [ - { - type: { - names: [ - 'Array.' - ] - } - } - ] - }; - - var html = helper.getSignatureReturns(mockDoclet); - expect(html).not.toContain('Array.'); - expect(html).toContain('Array.<string>'); - }); - - it("returns an empty array if the doclet has no returns", function() { - var doc = new doclet.Doclet('/** @function myFunction */', {}), - returns = helper.getSignatureReturns(doc); - - expect(Array.isArray(returns)).toBe(true); - expect(returns.length).toBe(0); - }); - - it("returns an empty array if the doclet has @returns but with no type", function() { - var doc = new doclet.Doclet('/** @function myFunction\n@returns an interesting result.*/', {}), - returns = helper.getSignatureReturns(doc); - - expect(Array.isArray(returns)).toBe(true); - expect(returns.length).toBe(0); - }); - - it("creates links for return types if relevant", function() { - // make some links. - helper.longnameToUrl.MyClass = 'MyClass.html'; - - var doc = new doclet.Doclet('/** @function myFunction\n@returns {number|MyClass} an interesting result.*/', {}), - returns = helper.getSignatureReturns(doc); - - expect(returns.length).toBe(2); - expect(returns).toContain('MyClass'); - expect(returns).toContain('number'); - - delete helper.longnameToUrl.MyClass; - }); - - it("uses the cssClass parameter for links if it is provided", function() { - // make some links. - helper.longnameToUrl.MyClass = 'MyClass.html'; - - var doc = new doclet.Doclet('/** @function myFunction\n@returns {number|MyClass} an interesting result.*/', {}), - returns = helper.getSignatureReturns(doc, 'myCssClass'); - - expect(returns.length).toBe(2); - expect(returns).toContain('MyClass'); - expect(returns).toContain('number'); - - delete helper.longnameToUrl.MyClass; - }); - }); - - describe("getAncestorLinks", function() { - // make a hierarchy. - var lackeys = new doclet.Doclet('/** @member lackeys\n@memberof module:mafia/gangs.Sharks~Henchman\n@instance*/', {}), - henchman = new doclet.Doclet('/** @class Henchman\n@memberof module:mafia/gangs.Sharks\n@inner */', {}), - gang = new doclet.Doclet('/** @namespace module:mafia/gangs.Sharks */', {}), - mafia = new doclet.Doclet('/** @module mafia/gangs */', {}), - data = taffy([lackeys, henchman, gang, mafia]); - - // register some links - it("returns an empty array if there are no ancestors", function() { - var links = helper.getAncestorLinks(data, mafia); - expect(Array.isArray(links)).toBe(true); - expect(links.length).toBe(0); - }); - - it("returns an array of ancestor names (with preceding punctuation) if there are ancestors, the direct ancestor with following punctuation too", function() { - var links = helper.getAncestorLinks(data, lackeys); - expect(links.length).toBe(3); - expect(links).toContain('~Henchman#'); - expect(links).toContain('.Sharks'); - expect(links).toContain('mafia/gangs'); - - links = helper.getAncestorLinks(data, henchman); - expect(links.length).toBe(2); - expect(links).toContain('.Sharks~'); - expect(links).toContain('mafia/gangs'); - - links = helper.getAncestorLinks(data, gang); - expect(links.length).toBe(1); - expect(links).toContain('mafia/gangs.'); - }); - - it("adds links if they exist", function() { - // register some links - helper.longnameToUrl['module:mafia/gangs'] = 'mafia_gangs.html'; - helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman'] = 'henchman.html'; - - var links = helper.getAncestorLinks(data, lackeys); - expect(links.length).toBe(3); - expect(links).toContain('~Henchman#'); - expect(links).toContain('.Sharks'); - expect(links).toContain('mafia/gangs'); - - delete helper.longnameToUrl['module:mafia/gangs']; - delete helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman']; - }); - - it("adds cssClass to any link", function() { - // register some links - helper.longnameToUrl['module:mafia/gangs'] = 'mafia_gangs.html'; - helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman'] = 'henchman.html'; - - var links = helper.getAncestorLinks(data, lackeys, 'myClass'); - expect(links.length).toBe(3); - expect(links).toContain('~Henchman#'); - expect(links).toContain('.Sharks'); - expect(links).toContain('mafia/gangs'); - - delete helper.longnameToUrl['module:mafia/gangs']; - delete helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman']; - }); - }); - - describe("addEventListeners", function() { - var doclets = taffy(jasmine.getDocSetFromFile('test/fixtures/listenstag.js').doclets), - ev = helper.find(doclets, {longname: 'module:myModule.event:MyEvent'})[0], - ev2 = helper.find(doclets, {longname: 'module:myModule~Events.event:Event2'})[0], - ev3 = helper.find(doclets, {longname: 'module:myModule#event:Event3'})[0]; - - helper.addEventListeners(doclets); - - it("adds a 'listeners' array to events with the longnames of the listeners", function() { - expect(Array.isArray(ev.listeners)).toBe(true); - expect(Array.isArray(ev2.listeners)).toBe(true); - - expect(ev.listeners.length).toBe(2); - expect(ev.listeners).toContain('module:myModule~MyHandler'); - expect(ev.listeners).toContain('module:myModule~AnotherHandler'); - - expect(ev2.listeners.length).toBe(1); - expect(ev2.listeners).toContain('module:myModule~MyHandler'); - }); - - it("does not add listeners for events with no listeners", function() { - expect(ev3.listeners).not.toBeDefined(); - }); - - it("does not make spurious doclets if something @listens to a non-existent symbol", function() { - expect(helper.find(doclets, {longname: 'event:fakeEvent'}).length).toBe(0); - }); - }); - - describe("prune", function() { - - var array = [ - // keep - {undocumented: false}, - // keep - {ignore: false}, - // keep - {memberof: 'SomeClass'}, - // prune - {undocumented: true}, - // prune - {ignore: true}, - // prune - {memberof: ''} - ]; - var arrayPrivate = [ - // prune (unless env.opts.private is truthy) - {access: 'private'} - ]; - var keep = array.slice(0, 3); - - it('should prune the correct members', function() { - var pruned = helper.prune( taffy(array) )().get(); - compareObjectArrays(keep, pruned); - }); - - it('should prune private members if env.opts.private is falsy', function() { - var priv = !!env.opts.private; - - env.opts.private = false; - var pruned = helper.prune( taffy(arrayPrivate) )().get(); - compareObjectArrays([], pruned); - - env.opts.private = !!priv; - }); - - it('should not prune private members if env.opts.private is truthy', function() { - var priv = !!env.opts.private; - - env.opts.private = true; - var pruned = helper.prune( taffy(arrayPrivate) )().get(); - compareObjectArrays(arrayPrivate, pruned); - - env.opts.private = !!priv; - }); - }); - - describe("registerLink", function() { - it("adds an entry to exports.longnameToUrl", function() { - helper.longnameToUrl.MySymbol = 'asdf.html'; - - expect(helper.longnameToUrl.MySymbol).toBeDefined(); - expect(helper.longnameToUrl.MySymbol).toBe('asdf.html'); - - delete helper.longnameToUrl.MySymbol; - }); - - it("allows linkto to work", function() { - helper.registerLink('MySymbol', 'asdf.html'); - - expect(helper.linkto('MySymbol')).toBe('MySymbol'); - - delete helper.longnameToUrl.MySymbol; - }); - }); - - describe("tutorialToUrl", function() { - var lenient = !!env.opts.lenient; - - function missingTutorial() { - var url = helper.tutorialToUrl("be-a-perfect-person-in-just-three-days"); - } - - beforeEach(function() { - spyOn(console, 'log'); - helper.setTutorials(resolver.root); - }); - - afterEach(function() { - helper.setTutorials(null); - env.opts.lenient = lenient; - }); - - it('throws an exception if the tutorial is missing and the lenient option is not enabled', function() { - env.opts.lenient = false; - expect(missingTutorial).toThrow(); - }); - - it('does not throw an exception if the tutorial is missing and the lenient option is enabled', function() { - env.opts.lenient = true; - - expect(missingTutorial).not.toThrow(); - }); - - it("does not return a tutorial if its name is a reserved JS keyword and it doesn't exist", function() { - env.opts.lenient = false; - expect(function () { helper.tutorialToUrl('prototype'); }).toThrow(); - }); - - it("creates links to tutorials if they exist", function() { - // NOTE: we have to set lenient = true here because otherwise JSDoc will - // cry when trying to resolve the same set of tutorials twice (once - // for the tutorials tests, and once here). - env.opts.lenient = true; - - // load the tutorials we already have for the tutorials tests - resolver.load(__dirname + "/test/tutorials/tutorials"); - resolver.resolve(); - - var url = helper.tutorialToUrl('test'); - expect(typeof url).toBe('string'); - expect(url).toBe('tutorial-test.html'); - }); - - it("creates links for tutorials where the name is a reserved JS keyword", function() { - var url = helper.tutorialToUrl('constructor'); - expect(typeof url).toBe('string'); - expect(url).toBe('tutorial-constructor.html'); - }); - - it("returns the same link if called multiple times on the same tutorial", function() { - expect(helper.tutorialToUrl('test2')).toBe(helper.tutorialToUrl('test2')); - }); - }); - - describe("toTutorial", function() { - var lenient = !!env.opts.lenient; - - function missingParam() { - helper.toTutorial(); - } - - afterEach(function() { - env.opts.lenient = lenient; - helper.setTutorials(null); - }); - - beforeEach(function () { - helper.setTutorials(resolver.root); - }); - - it('throws an exception if the first param is missing and the lenient option is not enabled', function() { - env.opts.lenient = false; - - expect(missingParam).toThrow(); - }); - - it('does not throw an exception if the first param is missing and the lenient option is enabled', function() { - spyOn(console, 'log'); - env.opts.lenient = true; - - expect(missingParam).not.toThrow(); - }); - - // missing tutorials - it("returns the tutorial name if it's missing and no missingOpts is provided", function() { - helper.setTutorials(resolver.root); - var link = helper.toTutorial('qwerty'); - expect(link).toBe('qwerty'); - }); - - it("returns the tutorial name wrapped in missingOpts.tag if provided and the tutorial is missing", function() { - var link = helper.toTutorial('qwerty', 'lkjklqwerty', {tag: 'span'}); - expect(link).toBe('qwerty'); - }); - - it("returns the tutorial name wrapped in missingOpts.tag with class missingOpts.classname if provided and the tutorial is missing", function() { - var link = helper.toTutorial('qwerty', 'lkjklqwerty', {classname: 'missing'}); - expect(link).toBe('qwerty'); - - link = helper.toTutorial('qwerty', 'lkjklqwerty', {tag: 'span', classname: 'missing'}); - expect(link).toBe('qwerty'); - }); - - it("prefixes the tutorial name with missingOpts.prefix if provided and the tutorial is missing", function() { - var link = helper.toTutorial('qwerty', 'lkjklqwerty', {tag: 'span', classname: 'missing', prefix: 'TODO-'}); - expect(link).toBe('TODO-qwerty'); - - link = helper.toTutorial('qwerty', 'lkjklqwerty', {prefix: 'TODO-'}); - expect(link).toBe('TODO-qwerty'); - - link = helper.toTutorial('qwerty', 'lkjklqwerty', {prefix: 'TODO-', classname: 'missing'}); - expect(link).toBe('TODO-qwerty'); - }); - - // now we do non-missing tutorials. - it("returns a link to the tutorial if not missing", function() { - // NOTE: we have to set lenient = true here because otherwise JSDoc will - // cry when trying to resolve the same set of tutorials twice (once - // for the tutorials tests, and once here). - env.opts.lenient = true; - spyOn(console, 'log'); - - // load the tutorials we already have for the tutorials tests - resolver.load(__dirname + "/test/tutorials/tutorials"); - resolver.resolve(); - - - var link = helper.toTutorial('constructor', 'The Constructor tutorial'); - expect(link).toBe('The Constructor tutorial'); - }); - - it("uses the tutorial's title for the link text if no content parameter is provided", function() { - var link = helper.toTutorial('test'); - expect(link).toBe('Test tutorial'); - }); - - it("does not apply any of missingOpts if the tutorial was found", function() { - var link = helper.toTutorial('test', '', {tag: 'span', classname: 'missing', prefix: 'TODO-'}); - expect(link).toBe('Test tutorial'); - }); - }); - - // couple of convenience functions letting me set conf variables and restore - // them back to the originals later. - function setConfTemplatesVariables(hash) { - var keys = Object.keys(hash); - var storage = {}; - for (var i = 0; i < keys.length; ++i) { - storage[keys[i]] = env.conf.templates[keys[i]]; - // works because hash[key] is a scalar not an array/object - env.conf.templates[keys[i]] = hash[keys[i]]; - } - return storage; - } - - function restoreConfTemplates(storage) { - var keys = Object.keys(storage); - for (var i = 0; i < keys.length; ++i) { - env.conf.templates[keys[i]] = storage[keys[i]]; - } - } - - describe("resolveLinks", function() { - it('should translate {@link test} into a HTML link.', function() { - var input = 'This is a {@link test}.', - output = helper.resolveLinks(input); - - expect(output).toBe('This is a test.'); - }); - - it('should translate {@link unknown} into a simple text.', function() { - var input = 'This is a {@link unknown}.', - output = helper.resolveLinks(input); - - expect(output).toBe('This is a unknown.'); - }); - - it('should translate {@link test} into a HTML links multiple times.', function() { - var input = 'This is a {@link test} and {@link test}.', - output = helper.resolveLinks(input); - - expect(output).toBe('This is a test and test.'); - }); - - it('should translate [hello there]{@link test} into a HTML link with the custom content.', function() { - var input = 'This is a [hello there]{@link test}.', - output = helper.resolveLinks(input); - - expect(output).toBe('This is a hello there.'); - }); - - it('should ignore [hello there].', function() { - var input = 'This is a [hello there].', - output = helper.resolveLinks(input); - - expect(output).toBe(input); - }); - - it('should translate http links in the tag', function() { - var input = 'Link to {@link http://github.com}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to http://github.com'); - }); - - it('should translate ftp links in the tag', function() { - var input = 'Link to {@link ftp://foo.bar}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to ftp://foo.bar'); - }); - - it('should allow pipe to be used as delimiter between href and text (external link)', function() { - var input = 'Link to {@link http://github.com|Github}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to Github'); - }); - - it('should allow pipe to be used as delimiter between href and text (symbol link)', function() { - var input = 'Link to {@link test|Test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to Test'); - }); - - it('should allow first space to be used as delimiter between href and text (external link)', function() { - var input = 'Link to {@link http://github.com Github}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to Github'); - }); - - it('should allow first space to be used as delimiter between href and text (symbol link)', function() { - var input = 'Link to {@link test My Caption}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to My Caption'); - }); - - it('if pipe and space are present in link tag, use pipe as the delimiter', function() { - var input = 'Link to {@link test|My Caption}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to My Caption'); - }); - - it('Test of {@linkcode } which should be in monospace', function() { - var input = 'Link to {@linkcode test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - }); - - it('Test of {@linkplain } which should be in normal font', function() { - var input = 'Link to {@linkplain test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - }); - - it('should be careful with linking to links whose names are reserved JS keywords', function() { - var input = 'Link to {@link constructor}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to constructor'); - }); - - it('should allow linebreaks between link tag and content', function() { - var input = 'This is a {@link\ntest}.', - output = helper.resolveLinks(input); - - expect(output).toBe('This is a test.'); - }); - - it('should allow tabs between link tag and content', function() { - var input = 'This is a {@link\ttest}.', - output = helper.resolveLinks(input); - - expect(output).toBe('This is a test.'); - }); - - // conf.monospaceLinks. check that - // a) it works - it('if conf.monospaceLinks is true, all {@link} should be monospace', function () { - var storage = setConfTemplatesVariables({monospaceLinks: true}); - var input = 'Link to {@link test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - restoreConfTemplates(storage); - }); - - // b) linkcode and linkplain are still respected - it('if conf.monospaceLinks is true, all {@linkcode} should still be monospace', function () { - var storage = setConfTemplatesVariables({monospaceLinks: true}); - var input = 'Link to {@linkcode test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - restoreConfTemplates(storage); - }); - - it('if conf.monospaceLinks is true, all {@linkplain} should still be plain', function () { - var storage = setConfTemplatesVariables({monospaceLinks: true}); - var input = 'Link to {@linkplain test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - restoreConfTemplates(storage); - }); - - // conf.cleverLinks. check that - // a) it works - it('if conf.cleverLinks is true, {@link symbol} should be in monospace', function () { - var storage = setConfTemplatesVariables({cleverLinks: true}); - var input = 'Link to {@link test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - restoreConfTemplates(storage); - }); - - it('if conf.cleverLinks is true, {@link URL} should be in plain text', function () { - var storage = setConfTemplatesVariables({cleverLinks: true}); - var input = 'Link to {@link http://github.com}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to http://github.com'); - restoreConfTemplates(storage); - }); - - // b) linkcode and linkplain are still respected - it('if conf.cleverLinks is true, all {@linkcode} should still be clever', function () { - var storage = setConfTemplatesVariables({cleverLinks: true}); - var input = 'Link to {@linkcode test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - restoreConfTemplates(storage); - }); - - it('if conf.cleverLinks is true, all {@linkplain} should still be plain', function () { - var storage = setConfTemplatesVariables({cleverLinks: true}); - var input = 'Link to {@linkplain test}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test'); - restoreConfTemplates(storage); - }); - - // c) if monospaceLinks is additionally `true` it is ignored in favour - // of cleverLinks - it('if conf.cleverLinks is true and so is conf.monospaceLinks, cleverLinks overrides', function () { - var storage = setConfTemplatesVariables({cleverLinks: true, monospaceLinks: true}); - var input = 'Link to {@link test} and {@link http://github.com}', - output = helper.resolveLinks(input); - expect(output).toBe('Link to test and http://github.com'); - restoreConfTemplates(storage); - }); - - }); - - describe("createLink", function() { - it('should create a url for a simple global.', function() { - var mockDoclet = { - kind: 'function', - longname: 'foo', - name: 'foo' - }, - url = helper.createLink(mockDoclet); - - expect(url).toBe('global.html#foo'); - }); - - it('should create a url for a namespace.', function() { - var mockDoclet = { - kind: 'namespace', - longname: 'foo', - name: 'foo' - }, - url = helper.createLink(mockDoclet); - - expect(url).toBe('foo.html'); - }); - - it('should create a url for a member of a namespace.', function() { - var mockDoclet = { - kind: 'function', - longname: 'ns.foo', - name: 'foo', - memberof: 'ns' - }, - url = helper.createLink(mockDoclet); - - expect(url).toBe('ns.html#foo'); - }); - - var nestedNamespaceDoclet = { - kind: 'function', - longname: 'ns1.ns2.foo', - name: 'foo', - memberof: 'ns1.ns2' - }; - var nestedNamespaceUrl; - - it('should create a url for a member of a nested namespace.', function() { - nestedNamespaceUrl = helper.createLink(nestedNamespaceDoclet); - - expect(nestedNamespaceUrl).toBe('ns1.ns2.html#foo'); - }); - - it('should return the same value when called twice with the same doclet.', function() { - var newUrl = helper.createLink(nestedNamespaceDoclet); - expect(newUrl).toBe(nestedNamespaceUrl); - }); - - it('should create a url for a name with invalid characters.', function() { - var mockDoclet = { - kind: 'function', - longname: 'ns1."!"."*foo"', - name: '"*foo"', - memberof: 'ns1."!"' - }, - url = helper.createLink(mockDoclet); - - expect(url).toEqual('_.html#"*foo"'); - }); - - it('should create a url for a function that is the only symbol exported by a module.', - function() { - var mockDoclet = { - kind: 'function', - longname: 'module:bar', - name: 'module:bar' - }; - var url = helper.createLink(mockDoclet); - - expect(url).toEqual('module-bar.html'); - }); - }); - - describe("resolveAuthorLinks", function() { - // convert Jane Doe to a mailto link. - it('should convert email addresses in angle brackets *after* a name to mailto links', function() { - var str = ' John Doe ', - out = helper.resolveAuthorLinks(str); - expect(out).toBe('John Doe'); - }); - - it('should HTML-safe author names', function() { - var str = ' John ', - out = helper.resolveAuthorLinks(str); - expect(out).toBe('' + helper.htmlsafe('John'); - }); - - it('should simply return the input string, HTML-safe, if no email is detected', function() { - var str = 'John Doe ', - out = helper.resolveAuthorLinks(str); - expect(out).toBe(helper.htmlsafe(str)); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/jsdoc/util/vm.js b/rsc/scripts/jsdoc/test/specs/jsdoc/util/vm.js deleted file mode 100644 index a141a4cc..00000000 --- a/rsc/scripts/jsdoc/test/specs/jsdoc/util/vm.js +++ /dev/null @@ -1,66 +0,0 @@ -/*global describe: true, expect: true, it: true, xit: true */ -describe("jsdoc/util/vm", function() { - var vm = require('jsdoc/util/vm'); - - it("should exist", function() { - expect(vm).toBeDefined(); - expect(typeof vm).toEqual('object'); - }); - - it("should export a 'RHINO' constant", function() { - expect(vm.RHINO).toBeDefined(); - expect(typeof vm.RHINO).toEqual('string'); - }); - - it("should export a 'NODEJS' constant", function() { - expect(vm.NODEJS).toBeDefined(); - expect(typeof vm.NODEJS).toEqual('string'); - }); - - it("should export a 'vm' property", function() { - expect(vm.vm).toBeDefined(); - expect(typeof vm.vm).toEqual('string'); - }); - - it("should export an 'isRhino' function", function() { - expect(vm.isRhino).toBeDefined(); - expect(typeof vm.isRhino).toEqual('function'); - }); - - it("should export an 'isNodejs' function", function() { - expect(vm.isNodejs).toBeDefined(); - expect(typeof vm.isNodejs).toEqual('function'); - }); - - - describe("vm", function() { - it("should match either 'vm.RHINO' or 'vm.NODEJS'", function() { - expect(vm.vm).toEqual(vm.RHINO || vm.NODEJS); - }); - - xit("should return the correct value for the current VM", function() { - // TODO: is there a reasonable test that doesn't just replicate getVm()? - }); - }); - - describe("isRhino", function() { - it("should return a boolean", function() { - expect( typeof vm.isRhino() ).toEqual('boolean'); - }); - - it("should reflect the value of 'vm.vm'", function() { - expect( vm.isRhino() ).toEqual(vm.vm === vm.RHINO ? true : false); - }); - }); - - describe("isNodejs", function() { - it("should return a boolean", function() { - expect( typeof vm.isNodejs() ).toEqual('boolean'); - }); - - it("should reflect the value of 'vm.vm'", function() { - expect( vm.isNodejs() ).toEqual(vm.vm === vm.NODEJS ? true : false); - }); - }); - -}); diff --git a/rsc/scripts/jsdoc/test/specs/jshint/jshint-clean.js b/rsc/scripts/jsdoc/test/specs/jshint/jshint-clean.js deleted file mode 100644 index e1a3492c..00000000 --- a/rsc/scripts/jsdoc/test/specs/jshint/jshint-clean.js +++ /dev/null @@ -1,72 +0,0 @@ -/*global app: true, beforeEach: true, describe: true, env: true, expect: true, it: true */ -var async = require('async'), - fs = require('jsdoc/fs'), - path = require('path'); - -var config = JSON.parse( fs.readFileSync( path.join(__dirname, '.jshintrc'), 'utf8' ) ); - -function jsHintCheck(filename, callback) { - var JSHINT = require('jshint').JSHINT; - var jsHintErrors; - - fs.readFile(filename, 'utf8', function(err, data) { - if (err) { - callback(err); - } else { - JSHINT(data, config); - if (JSHINT.errors.length) { - jsHintErrors = filename + ' is not JSHint clean: ' + JSON.stringify(JSHINT.errors); - } - - callback(null, jsHintErrors); - } - }); -} - -describe('jshint-clean', function() { - it('should generate JSHint errors for bad code', function(done) { - var file = path.join(__dirname, 'test', 'fixtures', 'jshint', 'badfile.js'); - - jsHintCheck(file, function(err, jsHintErrors) { - expect(err).toBeFalsy(); - expect(jsHintErrors).toBeDefined(); - done(); - }); - }); - - it('should not generate JSHint errors for good code', function(done) { - var file = path.join(__dirname, 'test', 'fixtures', 'jshint', 'goodfile.js'); - - jsHintCheck(file, function(err, jsHintErrors) { - expect(err).toBeFalsy(); - expect(jsHintErrors).toBeUndefined(); - done(); - }); - }); - - it('should not find JSHint errors in JSDoc', function(done) { - var files, - filter, - source; - - // check all .js files unless they're tests; rhino shim files that probably can't be - // delinted; or third-party modules - source = { - includePattern: '.+[\\|/]lib[\\|/].+\\.js$|.+[\\|/]plugins[\\|/]\\w+\\.js$', - excludePattern: '.+[\\|/]test[\\|/].+|.+[\\|/]node_modules[\\|/].+|.+[\\|/]Jake[\\|/].+' - }; - filter = new (require('jsdoc/src/filter').Filter)(source); - - files = app.jsdoc.scanner.scan([__dirname], 10, filter); - - async.forEach(files, function(file, cb) { - jsHintCheck(file, function(err, jsHintErrors) { - expect(jsHintErrors).toBeUndefined(); - cb(err); - }); - }, function(err) { - expect(err).toBeFalsy(); - done(); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/plugins/plugins.js b/rsc/scripts/jsdoc/test/specs/plugins/plugins.js deleted file mode 100644 index a989be1e..00000000 --- a/rsc/scripts/jsdoc/test/specs/plugins/plugins.js +++ /dev/null @@ -1,55 +0,0 @@ -/*global app: true, describe: true, expect: true, it: true, jasmine: true */ - -describe("plugins", function() { - var myGlobal = require('jsdoc/util/global'); - myGlobal.jsdocPluginsTest = myGlobal.jsdocPluginsTest || {}; - - require('jsdoc/plugins').installPlugins(['test/fixtures/testPlugin1', - 'test/fixtures/testPlugin2'], app.jsdoc.parser); - - var docSet = jasmine.getDocSetFromFile("test/fixtures/plugins.js", app.jsdoc.parser); - - it("should fire the plugin's event handlers", function() { - expect(myGlobal.jsdocPluginsTest.plugin1.fileBegin).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.fileBegin).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin1.beforeParse).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.beforeParse).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin1.jsdocCommentFound).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.jsdocCommentFound).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin1.symbolFound).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.symbolFound).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin1.newDoclet).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.newDoclet).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin1.fileComplete).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.fileComplete).toEqual(true); - - expect(myGlobal.jsdocPluginsTest.plugin2.fileBegin).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin2.fileBegin).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin2.beforeParse).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin2.beforeParse).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin2.jsdocCommentFound).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin2.jsdocCommentFound).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin2.symbolFound).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin2.symbolFound).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin2.newDoclet).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin2.newDoclet).toEqual(true); - expect(myGlobal.jsdocPluginsTest.plugin2.fileComplete).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin2.fileComplete).toEqual(true); - }); - - it("should add the plugin's tag definitions to the dictionary", function() { - var test = docSet.getByLongname("test"); - - expect(test[0].longname).toEqual("test"); - expect(test[0].foo).toEqual(true); - }); - - it("should call the plugin's visitNode function", function() { - expect(myGlobal.jsdocPluginsTest.plugin1.visitNode).toBeDefined(); - expect(myGlobal.jsdocPluginsTest.plugin1.visitNode).toEqual(true); - }); - - it("should not call a second plugin's visitNode function if the first stopped propagation", function() { - expect(myGlobal.jsdocPluginsTest.plugin2.visitNode).not.toBeDefined(); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/rhino/fs.js b/rsc/scripts/jsdoc/test/specs/rhino/fs.js deleted file mode 100644 index 5be21719..00000000 --- a/rsc/scripts/jsdoc/test/specs/rhino/fs.js +++ /dev/null @@ -1,4 +0,0 @@ -/*global describe: true */ -describe("fs", function() { - // TODO -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/rhino/os.js b/rsc/scripts/jsdoc/test/specs/rhino/os.js deleted file mode 100644 index 0f6a0aa6..00000000 --- a/rsc/scripts/jsdoc/test/specs/rhino/os.js +++ /dev/null @@ -1,4 +0,0 @@ -/*global describe: true */ -describe("os", function() { - // TODO -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/rhino/path.js b/rsc/scripts/jsdoc/test/specs/rhino/path.js deleted file mode 100644 index 942f3a73..00000000 --- a/rsc/scripts/jsdoc/test/specs/rhino/path.js +++ /dev/null @@ -1,35 +0,0 @@ -/*global describe: true, expect: true, it: true */ -describe("path", function() { - // TODO: more tests - var path = require('path'); - - var pathChunks = [ - "foo", - "bar", - "baz", - "qux.html" - ]; - var joinedPath = path.join.apply(this, pathChunks); - - describe("basename", function() { - it("should exist", function() { - expect(path.basename).toBeDefined(); - }); - - it("should be a function", function() { - expect(typeof path.basename).toEqual("function"); - }); - - it("should work correctly without an 'ext' parameter", function() { - expect( path.basename(joinedPath) ).toEqual( pathChunks[pathChunks.length - 1] ); - }); - - it("should work correctly with an 'ext' parameter", function() { - var fn = pathChunks[pathChunks.length - 1], - ext = Array.prototype.slice.call( fn, fn.indexOf(".") ).join(""); - bn = Array.prototype.slice.call( fn, 0, fn.indexOf(".") ).join(""); - - expect( path.basename(joinedPath, ext) ).toEqual(bn); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/abstracttag.js b/rsc/scripts/jsdoc/test/specs/tags/abstracttag.js deleted file mode 100644 index be2b7862..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/abstracttag.js +++ /dev/null @@ -1,20 +0,0 @@ -describe("@abstract tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/abstracttag.js'), - type = docSet.getByLongname('Thingy')[0], - pez = docSet.getByLongname('Thingy#pez')[0]; - - it("should have an undefined 'virtual' property with no '@abstract' tag", function() { - expect(type.virtual).toBeUndefined(); - }); - - it("should set the doclet's 'virtual' property to true when ' @abstract tag is present", function() { - expect(pez.virtual).toBe(true); - }); - - // same as... - - it("should set the doclet's 'virtual' property to true when ' @abstract tag is present", function() { - pez = docSet.getByLongname('OtherThingy#pez')[0]; - expect(pez.virtual).toBe(true); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/accesstag.js b/rsc/scripts/jsdoc/test/specs/tags/accesstag.js deleted file mode 100644 index 3bfa3973..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/accesstag.js +++ /dev/null @@ -1,24 +0,0 @@ -describe("@access tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/accesstag.js'), - foo = docSet.getByLongname('Thingy~foo')[0], - _bar = docSet.getByLongname('Thingy#_bar')[0], - pez = docSet.getByLongname('Thingy#pez')[0], - foo2 = docSet.getByLongname('OtherThingy~foo')[0], - _bar2 = docSet.getByLongname('OtherThingy#_bar')[0], - pez2 = docSet.getByLongname('OtherThingy#pez')[0]; - - it("should set the doclet's 'access' property to 'private' when there is an @access private tag", function() { - expect(foo.access).toBe('private'); - expect(foo2.access).toBe('private'); - }); - - it("should set the doclet's 'access' property to 'protected' when there is an @access protected tag", function() { - expect(_bar.access).toBe('protected'); - expect(_bar2.access).toBe('protected'); - }); - - it("should set no 'access' property on the doclet when there is an @access public tag", function() { - expect(pez.access).toBeUndefined(); - expect(pez2.access).toBeUndefined(); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/aliastag.js b/rsc/scripts/jsdoc/test/specs/tags/aliastag.js deleted file mode 100644 index 4b2396ef..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/aliastag.js +++ /dev/null @@ -1,11 +0,0 @@ -describe("@alias tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/alias.js'), - // there are two doclets with longname myObject, we want the second one - myObject = docSet.getByLongname('myObject')[1]; - - it("adds an 'alias' property to the doclet with the tag's value", function() { - expect(myObject.alias).toBeDefined(); - expect(myObject.alias).toBe('myObject'); - }); - // further tests (ensuring alias has the proper effect): documentation/alias.js -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/augmentstag.js b/rsc/scripts/jsdoc/test/specs/tags/augmentstag.js deleted file mode 100644 index fabc2ee0..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/augmentstag.js +++ /dev/null @@ -1,99 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ - describe("@augments tag", function() { - /*jshint unused: false */ - var docSet = jasmine.getDocSetFromFile('test/fixtures/augmentstag.js'), - foo = docSet.getByLongname('Foo')[0], - fooProp1 = docSet.getByLongname('Foo#prop1')[0], - fooProp2 = docSet.getByLongname('Foo#prop2')[0], - fooProp3 = docSet.getByLongname('Foo#prop3')[0], - fooMethod1 = docSet.getByLongname('Foo#method1')[0], - fooMethod2 = docSet.getByLongname('Foo#method2')[0], - bar = docSet.getByLongname('Bar')[0], - barProp1 = docSet.getByLongname('Bar#prop1')[0], - barProp2 = docSet.getByLongname('Bar#prop2')[0], - barProp3 = docSet.getByLongname('Bar#prop3')[0], - barMethod1 = docSet.getByLongname('Bar#method1')[0], - barMethod2 = docSet.getByLongname('Bar#method2')[0], - barMethod2All = docSet.getByLongname('Bar#method2'), - bazProp1 = docSet.getByLongname('Baz#prop1')[0], - bazProp1All = docSet.getByLongname('Baz#prop1'), - bazProp2 = docSet.getByLongname('Baz#prop2')[0], - bazProp3 = docSet.getByLongname('Baz#prop3')[0], - bazMethod1 = docSet.getByLongname('Baz#method1')[0], - bazMethod2 = docSet.getByLongname('Baz#method2')[0], - bazMethod3 = docSet.getByLongname('Baz#method3')[0], - - docSet2 = jasmine.getDocSetFromFile('test/fixtures/augmentstag2.js'), - qux = docSet2.getByLongname('Qux')[0], - - docSet3 = jasmine.getDocSetFromFile('test/fixtures/augmentstag3.js'), - FooMethod1 = docSet3.getByLongname('Foo#method1')[0], - BarMethod2 = docSet3.getByLongname('Bar#method2')[0], - FooBarMethod1 = docSet3.getByLongname('FooBar#method1')[0], - FooBarMethod2 = docSet3.getByLongname('FooBar#method2')[0]; - - it('When a symbol has an @augments tag, the doclet has a augments property that includes that value.', function() { - expect(typeof bar.augments).toBe('object'); - expect(bar.augments[0]).toBe('Foo'); - }); - - it('When an object is extended, the original is not modified', function() { - expect(fooProp3).toBeUndefined(); - }); - - it('When an object is extended, it inherits properties set in parent constructor', function() { - expect(fooProp1.memberof).toBe("Foo"); - expect(barProp1.memberof).toBe("Bar"); - expect(barProp1.description).toBe(fooProp1.description); - }); - - it('When an object is extended, it inherits properties set on parent prototype', function() { - expect(fooProp2.memberof).toBe("Foo"); - expect(barProp2.memberof).toBe("Bar"); - expect(barProp2.description).toBe(fooProp2.description); - }); - - it('When an object is extended, it inherits methods set on parent prototype', function() { - expect(fooMethod1.memberof).toBe("Foo"); - expect(barMethod1.memberof).toBe("Bar"); - expect(barMethod1.description).toBe(fooMethod1.description); - }); - - it('When an object is extended, it may override methods set on parent prototype', function() { - expect(fooMethod2.memberof).toBe("Foo"); - expect(fooMethod2.description).toBe("Second parent method."); - expect(barMethod2.memberof).toBe("Bar"); - expect(barMethod2.description).toBe("Second child method."); - }); - - it('When an object is extended, and it overrides an ancestor method, the child does not include docs for the ancestor method.', function() { - expect(barMethod2All.length).toBe(1); - }); - - it('When an object is extended, it inherits properties set on grandparent prototype', function() { - expect(fooProp1.memberof).toBe("Foo"); - expect(barProp1.memberof).toBe("Bar"); - expect(bazProp1.memberof).toBe("Baz"); - expect(bazProp1.description).toBe("Override prop1"); - expect(bazMethod1.memberof).toBe("Baz"); - expect(bazMethod2.memberof).toBe("Baz"); - expect(bazMethod3.memberof).toBe("Baz"); - }); - - it('When an object is extended, and it overrides an ancestor property, the child does not include docs for the ancestor property.', function() { - expect(bazProp1All.length).toBe(1); - }); - - it('When a symbol has an @augments tag, and the parent is not documented, the doclet still has an augments property', function() { - expect(typeof qux.augments).toBe('object'); - expect(qux.augments[0]).toBe('UndocumentedThing'); - }); - - - it('When a symbol @augments multiple parents, it inherits methods from all parents', function() { - expect(FooBarMethod1).toBeDefined(); - expect(FooBarMethod2).toBeDefined(); - expect(FooBarMethod1.description).toBe(FooMethod1.description); - expect(FooBarMethod2.description).toBe(BarMethod2.description); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/authortag.js b/rsc/scripts/jsdoc/test/specs/tags/authortag.js deleted file mode 100644 index 1a84b336..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/authortag.js +++ /dev/null @@ -1,18 +0,0 @@ -describe("@author tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/authortag.js'), - Thingy = docSet.getByLongname('Thingy')[0], - Thingy2 = docSet.getByLongname('Thingy2')[0]; - - it('When a symbol has a @author tag, the doclet has a author property with that value.', function() { - expect(Thingy.author).toBeDefined(); - expect(Array.isArray(Thingy.author)).toBe(true); - expect(Thingy.author[0]).toBe('Michael Mathews '); - }); - - it('When a symbol has multiple @author tags, the doclet has a author property, an array with those values.', function() { - expect(Thingy2.author).toBeDefined(); - expect(Array.isArray(Thingy2.author)).toBe(true); - expect(Thingy2.author).toContain('Jane Doe '); - expect(Thingy2.author).toContain('John Doe '); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/borrowstag.js b/rsc/scripts/jsdoc/test/specs/tags/borrowstag.js deleted file mode 100644 index 4a6fdf57..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/borrowstag.js +++ /dev/null @@ -1,24 +0,0 @@ -describe("@borrows tag", function() { - it('When a symbol has a @borrows-as tag, that is added to the symbol\'s "borrowed" property.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/borrowstag.js'), - util = docSet.getByLongname('util').filter(function($) { - return ! $.undocumented; - })[0]; - expect(util.borrowed.length).toBe(1); - expect(util.borrowed[0].from).toBe('trstr'); - expect(util.borrowed[0].as).toBe('trim'); - }); - - it('When a symbol has a @borrows tag, the borrowed symbol is added to the symbol.', function() { - var borrow = require('jsdoc/borrow'), - docSet = jasmine.getDocSetFromFile('test/fixtures/borrowstag2.js'); - - borrow.resolveBorrows(docSet.doclets); - - var str_rtrim = docSet.getByLongname('str.rtrim').filter(function($) { - return ! $.undocumented; - })[0]; - - expect(typeof str_rtrim).toBe('object'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/classdesctag.js b/rsc/scripts/jsdoc/test/specs/tags/classdesctag.js deleted file mode 100644 index 2a369cf1..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/classdesctag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@classdesc tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/classdesctag.js'), - doc = docSet.getByLongname('Foo')[0]; - - it('adds a classdesc property to the doclet with the description', function() { - expect(doc.classdesc).toBe('A description of the class.'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/classtag.js b/rsc/scripts/jsdoc/test/specs/tags/classtag.js deleted file mode 100644 index 0a28a54d..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/classtag.js +++ /dev/null @@ -1,14 +0,0 @@ -describe("@class tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/classtag.js'), - ticker = docSet.getByLongname('Ticker')[0], - news = docSet.getByLongname('NewsSource')[0]; - - it('When a symbol has a @class tag, the doclet has a kind property set to "class".', function() { - expect(ticker.kind).toBe('class'); - }); - - it('When a symbol has a @class tag with a value, the doclet has a name property set to that value.', function() { - expect(news.kind).toBe('class'); - expect(news.longname).toBe('NewsSource'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/constanttag.js b/rsc/scripts/jsdoc/test/specs/tags/constanttag.js deleted file mode 100644 index e33ae980..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/constanttag.js +++ /dev/null @@ -1,28 +0,0 @@ -describe("@constant tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constanttag.js'), - FOO = docSet.getByLongname('FOO')[0], - BAR = docSet.getByLongname('BAR')[0], - BAZ = docSet.getByLongname('BAZ')[0]; - - it("sets the doclet's 'kind' property to 'constant'", function() { - expect(FOO.kind).toBe('constant'); - expect(BAR.kind).toBe('constant'); - expect(BAZ.kind).toBe('constant'); - }); - - it("If used as a standalone, takes the name from the code", function() { - expect(FOO.name).toBe('FOO'); - }); - - it("If used with just a name, sets the doclet's name to that", function() { - expect(BAR.name).toBe('BAR'); - }); - - it("If used with a name and a type, sets the doclet's name and type appropriately", function() { - expect(BAZ.name).toBe('BAZ'); - expect(typeof BAZ.type).toBe('object'); - expect(BAZ.type.names).toBeDefined(); - expect(BAZ.type.names.length).toBe(1); - expect(BAZ.type.names[0]).toBe('string'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/constructortag.js b/rsc/scripts/jsdoc/test/specs/tags/constructortag.js deleted file mode 100644 index dd2bedad..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/constructortag.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("@constructor tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructortag.js'), - feed = docSet.getByLongname('Feed')[0]; - - it('When a symbol has an @constructor tag, it is documented as a class.', function() { - expect(feed.kind).toBe('class'); - }); - - it('When a symbol has an @constructor tag and a @class tag, the value of the @class tag becomes the classdesc property.', function() { - expect(feed.classdesc).toBe('Describe your class here.'); - expect(feed.description).toBe('Describe your constructor function here.'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/constructstag.js b/rsc/scripts/jsdoc/test/specs/tags/constructstag.js deleted file mode 100644 index a7198a4c..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/constructstag.js +++ /dev/null @@ -1,54 +0,0 @@ -describe("@constructs tag", function() { - - it('When a symbol has an @constructs tag, it is documented as a class with that name.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag.js'), - textblock = docSet.getByLongname('TextBlock')[0]; - - expect(textblock.kind).toBe('class'); - expect(textblock.longname).toBe('TextBlock'); - }); - - it('When a symbol has an @constructs tag, it is documented as a class.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag2.js'), - menu = docSet.getByLongname('Menu')[0]; - - expect(menu.name).toBe('Menu'); - expect(menu.kind).toBe('class'); - }); - - it('When a function symbol has an @constructs tag, any this-variables are ducumented as instance members of the class.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag3.js'), - personName = docSet.getByLongname('Person#name')[0]; - - expect(personName.memberof).toBe('Person'); - expect(personName.scope).toBe('instance'); - }); - - it('When a function symbol has an @constructs tag with no value, in a @lends block with a "Name#" value, the function is documented as a constructor of "Name".', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag4.js'), - person = docSet.getByLongname('Person').filter(function($) { - return ! $.undocumented; - })[0]; - - expect(person.kind).toBe('class'); - }); - - it('When a function symbol has an @constructs tag with no value, any this-variables are documented as instance members of the class.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag4.js'), - personName = docSet.getByLongname('Person#name')[0]; - - expect(personName.memberof).toBe('Person'); - expect(personName.scope).toBe('instance'); - }); - - it('When a object literal property has an @constructs tag with no value, and the object has a @lends, the property is documented as the lent class.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag5.js'), - duck = docSet.getByLongname('Duck').filter(function($) { - return ! $.undocumented; - })[0]; - - expect(duck.longname).toBe('Duck'); - expect(duck.kind).toBe('class'); - expect(duck.description).toBe('Constructs a duck.'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/copyrighttag.js b/rsc/scripts/jsdoc/test/specs/tags/copyrighttag.js deleted file mode 100644 index c9c7a5f1..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/copyrighttag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@copyright tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/copyrighttag.js'), - Thingy = docSet.getByLongname('Thingy')[0]; - - it('When a symbol has a @copyright tag, the doclet has a copyright property with that value.', function() { - expect(Thingy.copyright).toBe('(c) 2011 Michael Mathews'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/defaulttag.js b/rsc/scripts/jsdoc/test/specs/tags/defaulttag.js deleted file mode 100644 index ca4b086b..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/defaulttag.js +++ /dev/null @@ -1,39 +0,0 @@ -describe("@default tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/defaulttag.js'), - request = (docSet.getByLongname('request') || [])[0], - response = (docSet.getByLongname('response') || [])[0], - rcode = (docSet.getByLongname('rcode') || [])[0], - rvalid = (docSet.getByLongname('rvalid') || [])[0], - rerrored = (docSet.getByLongname('rerrored') || [])[0], - win = (docSet.getByLongname('win') || [])[0]; - header = (docSet.getByLongname('header') || [])[0]; - - it('When symbol set to null has a @default tag with no text, the doclet\'s defaultValue property should be: null', function() { - expect(request.defaultvalue).toBe('null'); - }); - - it('When symbol set to a string has a @default tag with no text, the doclet\'s defaultValue property should be that quoted string', function() { - expect(response.defaultvalue).toBe('"ok"'); - }); - - it('When symbol set to a number has a @default tag with no text, the doclet\'s defaultValue property should be that number.', function() { - expect(rcode.defaultvalue).toBe('200'); - }); - - it('When symbol has a @default tag with text, the doclet\'s defaultValue property should be that text.', function() { - expect(win.defaultvalue).toBe('the parent window'); - }); - - it('When symbol has a @default tag with true.', function() { - expect(rvalid.defaultvalue).toBe('true'); - }); - - it('When symbol has a @default tag with false.', function() { - expect(rerrored.defaultvalue, 'false'); - }); - - it('When symbol has a @default tag with a function call.', function() { - expect(header.defaultvalue).toBeUndefined(); - }); - -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/deprecatedtag.js b/rsc/scripts/jsdoc/test/specs/tags/deprecatedtag.js deleted file mode 100644 index 0e60ce29..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/deprecatedtag.js +++ /dev/null @@ -1,14 +0,0 @@ -describe("@deprecated tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/deprecatedtag.js'), - foo = docSet.getByLongname('foo')[0], - bar = docSet.getByLongname('bar')[0]; - - it('When a symbol has a @deprecated tag with no value, the doclet has a deprecated property set to true.', function() { - expect(foo.deprecated).toBe(true); - }); - - it('When a symbol has a @deprecated tag with a value, the doclet has a deprecated property set to that value.', function() { - expect(bar.deprecated).toBe('since version 2.0'); - }); - -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/descriptiontag.js b/rsc/scripts/jsdoc/test/specs/tags/descriptiontag.js deleted file mode 100644 index 855280dc..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/descriptiontag.js +++ /dev/null @@ -1,15 +0,0 @@ -describe("@description tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/descriptiontag.js'), - doc = docSet.getByLongname('x')[0], - doc2 = docSet.getByLongname('y')[0]; - - it("sets the doclet's 'description' property to the description", function() { - expect(doc2.description).toBeDefined(); - expect(doc2.description).toBe('lkjasdf'); - }); - - it("overrides the default description", function() { - expect(doc.description).toBeDefined(); - expect(doc.description).toBe('halb halb halb'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/enumtag.js b/rsc/scripts/jsdoc/test/specs/tags/enumtag.js deleted file mode 100644 index 4f48727e..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/enumtag.js +++ /dev/null @@ -1,31 +0,0 @@ -describe("@enum tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/enumtag.js'), - tristate = docSet.getByLongname('TriState')[0]; - - it('When a symbol has a @enum tag, it has a properties array.', function() { - expect(typeof tristate.properties).toBe('object'); - }); - - it('If no @type is given for the property it is inherted from the enum.', function() { - expect(tristate.properties[0].type.names.join(', ')).toBe('number'); - }); - - it('If no no comment is given for the property it is still included in the enum.', function() { - expect(tristate.properties[1].longname).toBe('TriState.FALSE'); - expect(tristate.properties[1].undocumented).toBeUndefined(); - }); - - it('A property of an enum gets its defaultvalue set.', function() { - expect(tristate.properties[1].defaultvalue).toBe('-1'); - }); - - it('If a @type is given for the property it is reflected in the property value.', function() { - expect(tristate.properties[2].type.names.join(', ')).toBe('boolean'); - }); - - it('An enum does not contain any circular references.', function() { - var dump = require("jsdoc/util/dumper").dump; - - expect( dump(tristate) ).not.toMatch(""); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/eventfirestag.js b/rsc/scripts/jsdoc/test/specs/tags/eventfirestag.js deleted file mode 100644 index 55d86f4a..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/eventfirestag.js +++ /dev/null @@ -1,30 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe('@event and @fires/@emits tags', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/eventfirestag.js'), - snowballMethod = docSet.getByLongname('Hurl#snowball')[0], - snowballEvent = docSet.getByLongname('Hurl#event:snowball')[0], - footballMatchMethod = docSet.getByLongname('Hurl#footballMatch')[0]; - - // @event tag - it('When a symbol has an @event tag, the doclet is of kind "event".', function() { - expect(snowballEvent.kind).toBe('event'); - }); - - // @fires/@emits tag - it('When a symbol has a @fires tag, the doclet has an array named "fires".', function() { - expect(typeof snowballMethod.fires).toBe('object'); - }); - - it('When a symbol has an @emits tag, the doclet has an array named "fires".', function() { - expect(typeof footballMatchMethod.fires).toBe('object'); - }); - - it('When a symbol has a "fires" array, the members have the "event:" namespace.', function() { - expect(snowballMethod.fires[0]).toBe('Hurl#event:snowball'); - }); - - it('When a symbol has a "fires" array with a name that already has an "event:" namespace, ' + - 'it does not have a second namespace applied.', function() { - expect(snowballMethod.fires[1]).toBe('Hurl#event:brick'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/exampletag.js b/rsc/scripts/jsdoc/test/specs/tags/exampletag.js deleted file mode 100644 index 8d1673c6..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/exampletag.js +++ /dev/null @@ -1,22 +0,0 @@ -describe("@example tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exampletag.js'), - doc = docSet.getByLongname('x')[0], - doc2 = docSet.getByLongname('y')[0], - txt = 'console.log("foo");\nconsole.log("bar");', - txt2 = 'Example 2\n1 + 2;'; - - it("creates an 'examples' property on the doclet with the example", function() { - expect(doc.examples).toBeDefined(); - expect(Array.isArray(doc.examples)).toBe(true); - expect(doc.examples.length).toBe(1); - expect(doc.examples).toContain(txt); - }); - - it("can be specified multiple times on one doclet", function() { - expect(doc2.examples).toBeDefined(); - expect(Array.isArray(doc2.examples)).toBe(true); - expect(doc2.examples.length).toBe(2); - expect(doc2.examples).toContain(txt); - expect(doc2.examples).toContain(txt2); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/exceptiontag.js b/rsc/scripts/jsdoc/test/specs/tags/exceptiontag.js deleted file mode 100644 index 40d3a0c4..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/exceptiontag.js +++ /dev/null @@ -1,17 +0,0 @@ -describe("@exception tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exceptiontag.js'), - foo = docSet.getByLongname('foo')[0], - bar = docSet.getByLongname('bar')[0], - pez = docSet.getByLongname('pez')[0]; - - it('When a symbol has an @exception tag, the doclet has a exception property set to that value.', function() { - expect(typeof foo.exceptions).toBe('object'); - expect(foo.exceptions.length).toBe(1); - - expect(typeof bar.exceptions).toBe('object'); - expect(bar.exceptions.length).toBe(1); - - expect(typeof pez.exceptions).toBe('object'); - expect(pez.exceptions.length).toBe(1); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/exportstag.js b/rsc/scripts/jsdoc/test/specs/tags/exportstag.js deleted file mode 100644 index 6d422754..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/exportstag.js +++ /dev/null @@ -1,89 +0,0 @@ -describe("@exports tag", function() { - - describe("object literals", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exportstag.js'), - shirt = docSet.getByLongname('module:my/shirt')[0], - color = docSet.getByLongname('module:my/shirt.color')[0], - tneck = docSet.getByLongname('module:my/shirt.Turtleneck')[0], - size = docSet.getByLongname('module:my/shirt.Turtleneck#size')[0]; - - it('When an objlit symbol has an @exports tag, the doclet is aliased to "module:" + the tag value.', function() { - expect(typeof shirt).toEqual('object'); - expect(shirt.alias).toEqual('my/shirt'); - }); - - it('When an objlit symbol has an @exports tag, the doclet\'s longname includes the "module:" namespace.', function() { - expect(shirt.longname).toEqual('module:my/shirt'); - }); - - it('When an objlit symbol has an @exports tag, the doclet kind is set to module.', function() { - expect(shirt.kind).toEqual('module'); - }); - - it('When an objlit symbol has an @exports tag, the objlit members are documented as members of the module.', function() { - expect(typeof color).toEqual('object'); - expect(color.memberof).toEqual('module:my/shirt'); - - expect(typeof tneck).toEqual('object'); - expect(typeof size).toEqual('object'); - }); - }); - - describe("functions", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exportstag2.js'), - coat = docSet.getByLongname('module:my/coat')[0], - wool = docSet.getByLongname('module:my/coat#wool')[0]; - - it('When a function symbol has an @exports tag, the doclet is aliased to "module:" + the tag value.', function() { - expect(typeof coat).toEqual('object'); - expect(coat.alias).toEqual('my/coat'); - }); - - it('When a function symbol has an @exports tag, the doclet\'s longname includes the "module:" namespace.', function() { - expect(coat.longname).toEqual('module:my/coat'); - }); - - it('When a function symbol has an @exports tag, the doclet kind is set to module.', function() { - expect(coat.kind).toEqual('module'); - }); - - it('When a function symbol has an @exports tag, the this members are documented as instance members of the module.', function() { - expect(typeof wool).toEqual('object'); - expect(wool.memberof).toEqual('module:my/coat'); - }); - }); - - describe("functions and 'exports' object", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exportstag3.js'), - html = docSet.getByLongname('module:html/utils')[0], - getstyle = docSet.getByLongname('module:html/utils.getStyleProperty')[0], - inhead = docSet.getByLongname('module:html/utils.isInHead')[0]; - - it('When a function symbol has an @exports tag and there is an objlit named "exports" the members are documented as members of the module.', function() { - expect(typeof getstyle).toEqual('object'); - expect(getstyle.memberof).toEqual('module:html/utils'); - }); - - it('When a function symbol has an @exports tag and there are members assinged to an "exports" name, the members are documented as members of the module.', function() { - expect(typeof inhead).toEqual('object'); - expect(inhead.memberof).toEqual('module:html/utils'); - }); - }); - - describe("inner classes", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/exportstag4.js'), - module = docSet.getByLongname('module:some/module')[0], - innerClass = docSet.getByLongname('module:some/module~myClass')[0], - method = docSet.getByLongname('module:some/module~myClass#myMethod')[0]; - - it('An inner class declared as a function in a module should be documented.', function() { - expect(typeof innerClass).toEqual('object'); - //expect(getstyle.memberof, 'module:html/utils'); - }); - - it('A method of an inner class declared as a function in a module should be documented.', function() { - expect(typeof method).toEqual('object'); - //expect(inhead.memberof, 'module:html/utils'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/functiontag.js b/rsc/scripts/jsdoc/test/specs/tags/functiontag.js deleted file mode 100644 index df63f6b9..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/functiontag.js +++ /dev/null @@ -1,18 +0,0 @@ -describe("@function tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/functiontag.js'), - doc = docSet.getByLongname('Foo')[0], - doc2 = docSet.getByLongname('Bar')[0]; - - it("sets the doclet's kind to 'function'", function() { - expect(doc.kind).toBe('function'); - expect(doc2.kind).toBe('function'); - }); - - it("sets the doclet's name to the tag value, if provided", function() { - expect(doc.name).toBe('Foo'); - expect(doc2.name).toBe('Bar'); - }); - - // parameter etc tests take place elsewhere: on its own, all @func does is - // set doclet.kind to function and sets the doclet's name. -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/globaltag.js b/rsc/scripts/jsdoc/test/specs/tags/globaltag.js deleted file mode 100644 index 3aeb34d8..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/globaltag.js +++ /dev/null @@ -1,24 +0,0 @@ -describe("@global tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/globaltag.js'); - - it('When an inner symbol has a @global tag it is documented as if it were global.', function() { - var found = docSet.getByLongname('foo').filter(function($) { - return ! $.undocumented; - }); - expect(found[0].name).toBe('foo'); - expect(found[0].longname).toBe('foo'); - expect(found[0].memberof).toBeUndefined(); - expect(found[0].scope).toBe('global'); - - }); - - it('When an nested symbol has a @global tag it is documented as if it were global.', function() { - var found = docSet.getByLongname('Bar').filter(function($) { - return ! $.undocumented; - }); - expect(found[0].name).toBe('Bar'); - expect(found[0].longname).toBe('Bar'); - expect(found[0].memberof).toBeUndefined(); - expect(found[0].scope).toBe('global'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/ignoretag.js b/rsc/scripts/jsdoc/test/specs/tags/ignoretag.js deleted file mode 100644 index 8536143c..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/ignoretag.js +++ /dev/null @@ -1,18 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("@ignore tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/ignoretag.js'), - foo = docSet.getByLongname('foo')[0]; - - it('When a symbol has an @ignore tag, the doclet has a ignore property set to true.', function() { - expect(foo.ignore).toBe(true); - }); - - it('When a symbol has an @ignore tag with a value an error is thrown', function() { - try { - docSet = jasmine.getDocSetFromFile('test/fixtures/ignoretag2.js'); - foo = docSet.getByLongname('foo')[0]; - } catch (e) { - expect(e instanceof Error).toBe(true); - } - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/kindtag.js b/rsc/scripts/jsdoc/test/specs/tags/kindtag.js deleted file mode 100644 index 49d9cd5d..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/kindtag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@kind tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/kindtag.js'), - doc = docSet.getByLongname('x')[0]; - it("sets the doclet's 'kind' property to the tag value", function() { - expect(doc.kind).toBeDefined(); - expect(doc.kind).toBe('function'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/lendstag.js b/rsc/scripts/jsdoc/test/specs/tags/lendstag.js deleted file mode 100644 index 0f4a685d..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/lendstag.js +++ /dev/null @@ -1,16 +0,0 @@ -describe("@lends tag", function() { - // see also specs/documentation/lends.js for tests on @lends behaviour. - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @lends */', {}), - doc2 = new doclet.Doclet('/** @lends MyClass# */', {}); - - it("sets the doclet's 'alias' property to the tag value or ", function() { - expect(doc.alias).toBe(''); - expect(doc2.alias).toBe('MyClass#'); - }); - - it("sets the doclet's 'undocumented' property to 'true'", function() { - expect(doc.undocumented).toBeTruthy(); - expect(doc2.undocumented).toBeTruthy(); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/licensetag.js b/rsc/scripts/jsdoc/test/specs/tags/licensetag.js deleted file mode 100644 index e37b1c63..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/licensetag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@license tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/licensetag.js'), - doc = docSet.getByLongname('x')[0]; - - it("sets the doclet's 'license' property to the tag value", function() { - expect(doc.license).toBe('GPL v2'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/listenstag.js b/rsc/scripts/jsdoc/test/specs/tags/listenstag.js deleted file mode 100644 index 742d5085..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/listenstag.js +++ /dev/null @@ -1,15 +0,0 @@ -describe("@listens tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/listenstag.js'), - doc = docSet.getByLongname('module:myModule~MyHandler')[0]; - - it("should create a 'listens' property on the doclet, an array, with the events that are listened to (with event namespace)", function() { - expect(Array.isArray(doc.listens)).toBeTruthy(); - expect(doc.listens).toContain('module:myModule.event:MyEvent'); - expect(doc.listens).toContain('module:myModule~Events.event:Event2'); - }); - - it("includes events even if non-existent", function() { - expect(doc.listens.length).toBe(3); - expect(doc.listens).toContain('event:fakeEvent'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/memberoftag.js b/rsc/scripts/jsdoc/test/specs/tags/memberoftag.js deleted file mode 100644 index 46d61201..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/memberoftag.js +++ /dev/null @@ -1,83 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe("@memberof tag", function() { - - it('When a symbol has an @member tag, the doclet has a long name that includes the parent.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftag.js'), - Data = docSet.getByLongname('mathlib.Data')[0], - point = docSet.getByLongname('mathlib.Data#point')[0]; - - expect(typeof Data).toBe('object'); - expect(typeof point).toBe('object'); - - expect(Data.memberof).toBe('mathlib'); - expect(Data.name).toBe('Data'); - }); - - it('A symbol within a namespace for which no scope is specified.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftag4.js'), - doOtherStuff = docSet.getByLongname('doStuff.doOtherStuff')[0]; - - expect(doOtherStuff).toBeDefined(); - expect(doOtherStuff.scope).toBe('static'); - }); - - it('A symbol in which name === memberof.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftag4.js'), - doStuff = docSet.getByLongname('doStuff.doStuff')[0]; - - expect(doStuff).toBeDefined(); - expect(doStuff.scope).toBe('static'); - }); - - describe ("static", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftag2.js'), - publish = docSet.getByLongname('Observable#publish')[0], - cache = docSet.getByLongname('Observable.cache')[0]; - - it('A symbol is documented as a static @memberof a class.', function() { - //it should appear as a static member of that class - expect(typeof cache).toBe('object'); - expect(cache.memberof).toBe('Observable'); - expect(cache.scope).toBe('static'); - expect(cache.name).toBe('cache'); - expect(cache.longname).toBe('Observable.cache'); - }); - - it('A symbol is documented as a static @memberof a class prototype.', function() { - //it should appear as an instance member of that class - expect(typeof publish).toBe('object'); - expect(publish.memberof).toBe('Observable'); - expect(publish.scope).toBe('instance'); - expect(publish.name).toBe('publish'); - expect(publish.longname).toBe('Observable#publish'); - }); - }); - - describe ("forced", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftagforced.js'), - maproutes = docSet.getByLongname('map.routes')[0], - datapointy = docSet.getByLongname('Data#point.y')[0]; - - it('A nested symbol with a @memberof! tag set to .', function() { - expect(maproutes.name, 'map.routes', 'Has a shortname that includes the nested names.'); - }); - - it('A nested symbol with a @memberof! tag set to another symbol.', function() { - expect(datapointy.name, 'point.y', 'Has a shortname that includes the nested names.'); - }); - }); - - it('A symbol that is a nested class with a @memberof tag.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftag3.js'), - tree = docSet.getByLongname('module:terrain.Forest#Tree')[0]; - - expect(tree.longname, 'module:terrain.Forest#Tree'); - }); - - it('A symbol that is an instance member of a nested class with a @memberof tag.', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/memberoftag3.js'), - leaf = docSet.getByLongname('module:terrain.Forest#Tree#leaf')[0]; - - expect(leaf.longname, 'module:terrain.Forest#Tree#leaf'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/membertag.js b/rsc/scripts/jsdoc/test/specs/tags/membertag.js deleted file mode 100644 index cfea6de3..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/membertag.js +++ /dev/null @@ -1,25 +0,0 @@ -describe("@member tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/membertag.js'), - doc = docSet.getByLongname('x')[0], - doc2 = docSet.getByLongname('foobar')[0], - doc3 = docSet.getByLongname('baz')[0]; - - it("sets the doclet's 'kind' property to 'member'", function() { - expect(doc.kind).toBe('member'); - expect(doc2.kind).toBe('member'); - expect(doc3.kind).toBe('member'); - }); - - it("If specified with a name, sets the doclet's name property", function() { - expect(doc.name).toBe('x'); - expect(doc2.name).toBe('foobar'); - expect(doc3.name).toBe('baz'); - }); - - it("If specified with a type and name, sets the doclet's type appropriately", function() { - expect(doc3.type).toBeDefined(); - expect(Array.isArray(doc3.type.names)).toBeTruthy(); - expect(doc3.type.names.length).toBe(1); - expect(doc3.type.names[0]).toBe('string'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/mixestag.js b/rsc/scripts/jsdoc/test/specs/tags/mixestag.js deleted file mode 100644 index 6bb4f827..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/mixestag.js +++ /dev/null @@ -1,19 +0,0 @@ -describe("@mixes tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/mixintag.js'), - FormButton = docSet.getByLongname('FormButton')[0], - MyClass = docSet.getByLongname('MyClass')[0]; - - it("When a symbol has a @mixes tag, it gets an array property 'mixes' with the name of the mixin", function() { - expect(FormButton.mixes).toBeDefined(); - expect(Array.isArray(FormButton.mixes)).toBe(true); - expect(FormButton.mixes.length).toBe(1); - expect(FormButton.mixes[0]).toBe('Eventful'); - }); - - it("A symbol can @mixes multiple mixins and they are all added.", function() { - expect(MyClass.mixes).toBeDefined(); - expect(MyClass.mixes.length).toBe(2); - expect(MyClass.mixes).toContain('Eventful'); - expect(MyClass.mixes).toContain('AnotherMixin'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/mixintag.js b/rsc/scripts/jsdoc/test/specs/tags/mixintag.js deleted file mode 100644 index 4c928fb2..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/mixintag.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("@mixin tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/mixintag.js'), - Eventful = docSet.getByLongname('Eventful')[0], - Mixin = docSet.getByLongname('AnotherMixin')[0]; - - it("When a symbol has a @mixin tag, the doclet's 'kind' property is set to 'mixin'", function() { - expect(Eventful.kind).toBe('mixin'); - }); - - it("When a symbol has a @mixin tag, its name is set to the tag's value (if present)", function() { - expect(Mixin).toBeDefined(); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/moduletag.js b/rsc/scripts/jsdoc/test/specs/tags/moduletag.js deleted file mode 100644 index e2b44e30..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/moduletag.js +++ /dev/null @@ -1,41 +0,0 @@ -describe("@module tag", function() { - describe("using 'this'", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/moduletag.js'), - book = docSet.getByLongname('module:bookshelf.Book')[0], - title = docSet.getByLongname('module:bookshelf.Book#title')[0]; - - it('When a global symbol starts with "this" and is in a file with a @module tag, the symbol is documented as a member of that module.', function() { - expect(typeof book).toBe('object'); - expect(book.memberof).toBe('module:bookshelf'); - }); - - it('When an inner symbol starts with "this" and is in a file with a @module tag, the symbol is documented as a member of its enclosing constructor.', function() { - expect(typeof title).toBe('object'); - expect(title.memberof).toBe('module:bookshelf.Book'); - }); - }); - - describe("misc", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/moduletag2.js'), - mixer = docSet.getByLongname('module:color/mixer').filter(function($) { - return ! $.undocumented; - })[0], - blend = docSet.getByLongname('module:color/mixer.blend')[0], - darken = docSet.getByLongname('module:color/mixer.darken')[0]; - - it('When a @module tag defines a module module, a symbol of kind "module" is documented', function() { - expect(typeof mixer).toBe('object'); - expect(mixer.kind).toBe('module'); - }); - - it('When an object literal is lent to a module with a @lends tag, A member of that object literal is documented as a member of the module', function() { - expect(typeof blend).toBe('object'); - expect(blend.kind).toBe('function'); - }); - - it('When a documented symbol is a member of a namespace "exports", it is documented as a member of the module', function() { - expect(typeof darken).toBe('object'); - expect(darken.kind).toBe('function'); - }); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/namespacetag.js b/rsc/scripts/jsdoc/test/specs/tags/namespacetag.js deleted file mode 100644 index 182ce0f3..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/namespacetag.js +++ /dev/null @@ -1,25 +0,0 @@ -describe("@namespace tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/namespacetag.js'), - doc = docSet.getByLongname('x')[0], - doc2 = docSet.getByLongname('Foo')[0], - doc3 = docSet.getByLongname('Bar')[0]; - - it("sets the doclet's kind to 'namespace'", function () { - expect(doc.kind).toBe('namespace'); - expect(doc2.kind).toBe('namespace'); - expect(doc3.kind).toBe('namespace'); - }); - - it("sets the doclet's name to the tag value (if provided)", function() { - expect(doc.name).toBe('x'); - expect(doc2.name).toBe('Foo'); - expect(doc3.name).toBe('Bar'); - }); - - it("sets the doclet's type (if provided in @namespace)", function() { - expect(doc3.type).toBeDefined(); - expect(Array.isArray(doc3.type.names)).toBeTruthy(); - expect(doc3.type.names.length).toBe(1); - expect(doc3.type.names[0]).toBe('function'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/overviewtag.js b/rsc/scripts/jsdoc/test/specs/tags/overviewtag.js deleted file mode 100644 index 6087be5b..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/overviewtag.js +++ /dev/null @@ -1,18 +0,0 @@ -/*global describe: true, env: true, expect: true, it: true */ - -describe("@overview tag", function() { - var parser = require('jsdoc/src/parser'), - srcParser = new parser.Parser(), - doclets; - - require('jsdoc/src/handlers').attachTo(srcParser); - doclets = srcParser.parse(__dirname + '/test/fixtures/file.js'); - - it('When a file overview tag appears in a doclet, the name of the doclet should contain the path to the file.', function() { - expect(doclets[0].name).toMatch(/^(fixtures[\/\\]file\.js)$/); - }); - - it("The name and longname should be equal", function() { - expect(doclets[0].name).toBe(doclets[0].longname); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/paramtag.js b/rsc/scripts/jsdoc/test/specs/tags/paramtag.js deleted file mode 100644 index 7145c83f..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/paramtag.js +++ /dev/null @@ -1,80 +0,0 @@ -describe("@param tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/paramtag.js'), - find = docSet.getByLongname('find')[0], - unbind = docSet.getByLongname('unbind')[0], - bind = docSet.getByLongname('bind')[0], - getElement = docSet.getByLongname('getElement')[0], - combine = docSet.getByLongname('combine')[0], - split = docSet.getByLongname('split')[0], - commit = docSet.getByLongname('commit')[0], - request = docSet.getByLongname('request')[0]; - - it('When a symbol has an @param tag with a type before the name, the doclet has a params property that includes that param.', function() { - expect(typeof find.params).toBe('object'); - expect(find.params.length).toBe(1); - expect(find.params[0].type.names.join(', ')).toBe('String, Array.'); - expect(find.params[0].name).toBe('targetName'); - expect(find.params[0].description).toBe('The name (or names) of what to find.'); - }); - - it('When a symbol has an @param tag with only a type and name, the doclet has a params property that includes that param.', function() { - expect(typeof bind.params).toBe('object'); - expect(bind.params.length).toBe(1); - expect(bind.params[0].type.names.join(', ')).toBe('function'); - expect(bind.params[0].name).toBe('callback'); - expect(bind.params[0].description).toBeUndefined(); - }); - - it('When a symbol has an @param tag with only a type, the doclet has a params property that includes that param.', function() { - expect(typeof unbind.params).toBe('object'); - expect(unbind.params.length).toBe(1); - expect(unbind.params[0].type.names.join(', ')).toBe('function'); - expect(unbind.params[0].description).toBeUndefined(); - }); - - it('When a symbol has an @param tag with no type, the doclet has a params property that includes that param.', function() { - expect(typeof getElement.params).toBe('object'); - expect(getElement.params.length).toBe(1); - expect(getElement.params[0].type).toBeUndefined(); - expect(getElement.params[0].name).toBe('id'); - expect(getElement.params[0].description).toBe('The id of the element.'); - }); - - it('When a symbol has an @param tag with a non-alpha name like "...", the doclet has a params property that includes that param.', function() { - expect(typeof combine.params).toBe('object'); - expect(combine.params.length).toBe(1); - expect(combine.params[0].type).toBeUndefined(); - expect(combine.params[0].name).toBe('...'); - expect(combine.params[0].description).toBe('Two or more elements.'); - }); - - it('When a symbol has an @param tag with name followed by a dash, the doclet has a params property that includes that param.', function() { - expect(typeof split.params).toBe('object'); - expect(split.params.length).toBe(1); - expect(split.params[0].type).toBeUndefined(); - expect(split.params[0].name).toBe('delimiter'); - expect(split.params[0].description).toBe('What to split on.'); - }); - - it('When a symbol has an @param tag with no name or type, the doclet has a params property that includes that param.', function() { - expect(typeof commit.params).toBe('object'); - expect(commit.params.length).toBe(1); - expect(commit.params[0].type).toBeUndefined(); - expect(commit.params[0].description).toBe('If true make the commit atomic.'); - }); - - it('When a symbol has a @param tag with no type but a name that indicates a default value or optional type, this is copied over to the params property.', function() { - expect(typeof request.params).toBe('object'); - expect(request.params.length).toBe(1); - expect(request.params[0].type).toBeUndefined(); - expect(request.params[0].name).toBe('async'); - expect(request.params[0].defaultvalue).toBe('true'); - expect(request.params[0].optional).toBe(true); - expect(request.params[0].description).toBe('whether to be asynchronous'); - }); - - it('When a symbol has an @param tag with no name and a name is given in the code, the doclet has a params property that includes that param with the name from the code.', function() { - expect(commit.params[0].name).toBe('atomic'); - }); - -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/privatetag.js b/rsc/scripts/jsdoc/test/specs/tags/privatetag.js deleted file mode 100644 index a4d5aceb..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/privatetag.js +++ /dev/null @@ -1,9 +0,0 @@ -describe("@private tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/privatetag.js'), - foo = docSet.getByLongname('Foo')[0], - bar = docSet.getByLongname('Foo#bar')[0]; - - it('When a symbol has an @private tag, the doclet has an access property that is "private".', function() { - expect(foo.access).toBe('private'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/propertytag.js b/rsc/scripts/jsdoc/test/specs/tags/propertytag.js deleted file mode 100644 index 5ef94231..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/propertytag.js +++ /dev/null @@ -1,15 +0,0 @@ -describe("@property tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/propertytag.js'), - myobject = docSet.getByLongname('myobject')[0]; - - it('When a symbol has an @property tag with a those properties appear in the parsed object.', function() { - expect(typeof myobject.properties).toBe('object'); - expect(myobject.properties.length).toBe(3); - expect(myobject.properties[0].name).toBe('defaults'); - expect(myobject.properties[1].name).toBe('defaults.a'); - expect(myobject.properties[2].name).toBe('defaults.b'); - expect(myobject.properties[0].description).toBe('The default values.'); - expect(myobject.properties[0].type.names[0]).toBe('Object'); - }); - -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/readonlytag.js b/rsc/scripts/jsdoc/test/specs/tags/readonlytag.js deleted file mode 100644 index 8465cb80..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/readonlytag.js +++ /dev/null @@ -1,9 +0,0 @@ -describe("@readonly tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/readonlytag.js'), - Collection = docSet.getByLongname('Collection')[0], - length = docSet.getByLongname('Collection#length')[0]; - - it('When a symbol has an @readonly tag, the doclet has an readonly property that is true.', function() { - expect(length.readonly).toBe(true); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/requirestag.js b/rsc/scripts/jsdoc/test/specs/tags/requirestag.js deleted file mode 100644 index 40eae164..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/requirestag.js +++ /dev/null @@ -1,14 +0,0 @@ -describe("@requires tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/requirestag.js'), - foo = docSet.getByLongname('foo')[0], - bar = docSet.getByLongname('bar')[0]; - - it('When a symbol has an @requires tag, the doclet has a requires property that includes that value, with the "module:" namespace added.', function() { - expect(typeof foo.requires).toBe('object'); - expect(foo.requires[0]).toBe('module:foo/helper'); - - expect(typeof bar.requires).toBe('object'); - expect(bar.requires[0]).toBe('module:foo'); - expect(bar.requires[1]).toBe('module:Pez#blat'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/returnstag.js b/rsc/scripts/jsdoc/test/specs/tags/returnstag.js deleted file mode 100644 index 2fcf2e59..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/returnstag.js +++ /dev/null @@ -1,18 +0,0 @@ -describe("@returns tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/returnstag.js'), - find = docSet.getByLongname('find')[0], - bind = docSet.getByLongname('bind')[0]; - - it('When a symbol has an @returns tag with a type and description, the doclet has a returns array that includes that return.', function() { - expect(typeof find.returns).toBe('object'); - expect(find.returns.length).toBe(1); - expect(find.returns[0].type.names.join(', ')).toBe('String, Array.'); - expect(find.returns[0].description).toBe('The names of the found item(s).'); - }); - - it('When a symbol has an @returns tag with only a description, the doclet has a returns array property that includes that return.', function() { - expect(typeof bind.returns).toBe('object'); - expect(bind.returns.length).toBe(1); - expect(bind.returns[0].description).toBe('The binding id.'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/scopetags.js b/rsc/scripts/jsdoc/test/specs/tags/scopetags.js deleted file mode 100644 index 0b18a58c..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/scopetags.js +++ /dev/null @@ -1,31 +0,0 @@ -describe('scope tags', function () { - var docSet = jasmine.getDocSetFromFile('test/fixtures/scopetags.js'); - - // @inner, @instance, @static (@global has its own file) - describe("@inner tag", function() { - var doc = docSet.getByLongname('module:scopetags~myInner')[0]; - - it("sets the doclet's 'scope' property to 'inner'", function() { - expect(doc.scope).toBeDefined(); - expect(doc.scope).toBe('inner'); - }); - }); - - describe("@instance tag", function() { - var doc = docSet.getByLongname('module:scopetags#myInstance')[0]; - - it("sets the doclet's 'scope' property to 'instance'", function() { - expect(doc.scope).toBeDefined(); - expect(doc.scope).toBe('instance'); - }); - }); - - describe("@static tag", function() { - var doc = docSet.getByLongname('module:scopetags.myStatic')[0]; - - it("sets the doclet's 'scope' property to 'static'", function() { - expect(doc.scope).toBeDefined(); - expect(doc.scope).toBe('static'); - }); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/seetag.js b/rsc/scripts/jsdoc/test/specs/tags/seetag.js deleted file mode 100644 index d6228a59..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/seetag.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("@see tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/seetag.js'), - foo = docSet.getByLongname('foo')[0], - bar = docSet.getByLongname('bar')[0]; - - it('When a symbol has an @see tag, the doclet has a see property that includes that value.', function() { - expect(typeof foo.see).toBe('object'); - expect(foo.see[0]).toBe('{@link bar}'); - - expect(typeof bar.see).toBe('object'); - expect(bar.see[0]).toBe('http://example.com/someref'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/sincetag.js b/rsc/scripts/jsdoc/test/specs/tags/sincetag.js deleted file mode 100644 index 91ab3d83..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/sincetag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@since tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/sincetag.js'), - foo = docSet.getByLongname('foo')[0]; - - it('When a symbol has an @since tag, the doclet has a since property set to true.', function() { - expect(foo.since).toBe('1.2.3'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/summarytag.js b/rsc/scripts/jsdoc/test/specs/tags/summarytag.js deleted file mode 100644 index a4627153..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/summarytag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@summary tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/summarytag.js'), - doc = docSet.getByLongname('Sam')[0]; - it("sets the doclet's 'summary' property to the tag value", function() { - expect(doc.summary).toBe('I do not like green eggs and ham!'); - }); -}); - diff --git a/rsc/scripts/jsdoc/test/specs/tags/thistag.js b/rsc/scripts/jsdoc/test/specs/tags/thistag.js deleted file mode 100644 index 5fac4ae6..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/thistag.js +++ /dev/null @@ -1,16 +0,0 @@ -describe("@this tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/thistag.js'), - setName = docSet.getByLongname('setName')[0], - fooName = docSet.getByLongname('Foo#name')[0]; - - it('When a symbol has a @this tag, the doclet has a this property that is set to that value.', function() { - expect(setName['this']).toBe('Foo'); - }); - - it('When a this symbol is documented inside a function with a @this tag, the symbol is documented as a member of that tags value.', function() { - expect(typeof fooName).toBe('object'); - expect(fooName.name).toBe('name'); - expect(fooName.memberof).toBe('Foo'); - expect(fooName.scope).toBe('instance'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/todotag.js b/rsc/scripts/jsdoc/test/specs/tags/todotag.js deleted file mode 100644 index 410bb55f..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/todotag.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("@todo tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/todotag.js'), - doc = docSet.getByLongname('x')[0]; - - it("adds the entries into a 'todo' array on the doclet", function() { - expect(doc.todo).toBeDefined(); - expect(Array.isArray(doc.todo)).toBeTruthy(); - expect(doc.todo.length).toBe(2); - - expect(doc.todo).toContain('something'); - expect(doc.todo).toContain('something else'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/tutorialtag.js b/rsc/scripts/jsdoc/test/specs/tags/tutorialtag.js deleted file mode 100644 index b334a266..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/tutorialtag.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("@tutorial tag", function() { - // these are tests for the block usage, not the inline usage. see util/templateHelper for that. - var docSet = jasmine.getDocSetFromFile('test/fixtures/tutorialtag.js'), - doc = docSet.getByLongname('x')[0]; - - it("adds the listed tutorials to a 'tutorials' array on the doclet", function () { - expect(Array.isArray(doc.tutorials)).toBeTruthy(); - expect(doc.tutorials.length).toBe(2); - expect(doc.tutorials).toContain('tute1'); - expect(doc.tutorials).toContain('tute2'); - }); -}); - diff --git a/rsc/scripts/jsdoc/test/specs/tags/typedeftag.js b/rsc/scripts/jsdoc/test/specs/tags/typedeftag.js deleted file mode 100644 index a3cacebb..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/typedeftag.js +++ /dev/null @@ -1,34 +0,0 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ -describe('@typedef tag', function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/typedeftag.js'); - var numberlike = docSet.getByLongname('calc.NumberLike')[0]; - var operator = docSet.getByLongname('calc.Operator')[0]; - var result = docSet.getByLongname('calc.Result')[0]; - - it('When a comment has a @typedef tag, the doclet has a kind property set to "typedef".', function() { - expect(numberlike.kind).toBe('typedef'); - }); - - it('When a comment has a @typedef tag with a type, the doclet has a type property set to that type.', function() { - expect(typeof numberlike.type).toBe('object'); - expect(typeof numberlike.type.names).toBe('object'); - expect(numberlike.type.names.length).toBe(2); - expect(numberlike.type.names[0]).toBe('string'); - expect(numberlike.type.names[1]).toBe('number'); - }); - - it('When a comment has a @typedef tag with a name, the doclet has a name property set to that name.', function() { - expect(numberlike.name).toBe('NumberLike'); - expect(numberlike.longname).toBe('calc.NumberLike'); - }); - - it('When a symbol has a @typedef tag without a name, the doclet has a name property set to the symbol name.', function() { - expect(operator.name).toBe('Operator'); - expect(operator.longname).toBe('calc.Operator'); - }); - - it('When a symbol has a @typedef tag with a name, the name in the tag takes precedence over the symbol name.', function() { - expect(result.name).toBe('Result'); - expect(result.longname).toBe('calc.Result'); - }); -}); diff --git a/rsc/scripts/jsdoc/test/specs/tags/typekind.js b/rsc/scripts/jsdoc/test/specs/tags/typekind.js deleted file mode 100644 index aea60db0..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/typekind.js +++ /dev/null @@ -1,15 +0,0 @@ -describe("@kind tag with type", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/typekind.js'), - blog = docSet.getByLongname('module:blog/server')[0], - port = docSet.getByLongname('module:blog/server.port')[0]; - - it('When a module symbol has an kind tag, that includes a {type} clause, the doclet has a type property set to that {type} clause', function() { - expect(typeof blog.type).toBe('object'); - expect(blog.type.names.join(', ')).toBe('ConnectServer'); - }); - - it('When a property symbol has an kind tag, that includes a {type} clause, the doclet has a type property set to that {type} clause', function() { - expect(typeof port.type).toBe('object'); - expect(port.type.names.join(', ')).toBe('number'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/typetag.js b/rsc/scripts/jsdoc/test/specs/tags/typetag.js deleted file mode 100644 index 055fa81d..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/typetag.js +++ /dev/null @@ -1,15 +0,0 @@ -describe("@type tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/typetag.js'), - foo = docSet.getByLongname('foo')[0], - bar = docSet.getByLongname('bar')[0]; - - it('When a symbol has an @type tag, the doclet has a type property set to that value\'s type.', function() { - expect(typeof foo.type).toBe('object'); - expect(typeof foo.type.names).toBe('object'); - expect(foo.type.names.join(', ')).toBe('string, Array.'); - }); - - it('When a symbol has an @type tag set to a plain string, the doclet has a type property set to that string as if it were a type.', function() { - expect(bar.type.names.join(', ')).toBe('integer'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/specs/tags/undocumentedtag.js b/rsc/scripts/jsdoc/test/specs/tags/undocumentedtag.js deleted file mode 100644 index 90052234..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/undocumentedtag.js +++ /dev/null @@ -1,13 +0,0 @@ -describe("@undocumented tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/undocumentedtag.js'), - doc = docSet.getByLongname('x')[0]; - - it("sets the doclet's 'undocumented' property to true", function () { - expect(doc.undocumented).toBeTruthy(); - }); - - it("clears the doclet's 'comment' property", function () { - expect(doc.comment).toBe(''); - }); -}); - diff --git a/rsc/scripts/jsdoc/test/specs/tags/versiontag.js b/rsc/scripts/jsdoc/test/specs/tags/versiontag.js deleted file mode 100644 index 1b50ada2..00000000 --- a/rsc/scripts/jsdoc/test/specs/tags/versiontag.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("@version tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/versiontag.js'), - foo = docSet.getByLongname('foo')[0]; - - it('When a symbol has an @version tag, the doclet has a version property set to that value.', function() { - expect(foo.version).toBe('1.2.3'); - }); -}); \ No newline at end of file diff --git a/rsc/scripts/jsdoc/test/tutorials/build.sh b/rsc/scripts/jsdoc/test/tutorials/build.sh deleted file mode 100644 index 8937f26d..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -rm -rf out -../../jsdoc -u tutorials src -d out diff --git a/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/asdf.html b/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/asdf.html deleted file mode 100644 index 1f8a6622..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/asdf.html +++ /dev/null @@ -1 +0,0 @@ -

      tutorial ASDF

      diff --git a/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/asdf.json b/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/asdf.json deleted file mode 100644 index c769dc54..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/asdf.json +++ /dev/null @@ -1 +0,0 @@ -{"title": "Conflicting title"} diff --git a/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/index.json b/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/index.json deleted file mode 100644 index 9ceb182f..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/duplicateDefined/index.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "asdf": { - "title": "Tutorial Asdf" - } -} diff --git a/rsc/scripts/jsdoc/test/tutorials/incomplete/parent.html b/rsc/scripts/jsdoc/test/tutorials/incomplete/parent.html deleted file mode 100644 index aa4a4ff9..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/incomplete/parent.html +++ /dev/null @@ -1,3 +0,0 @@ -

      Test.html

      - -

      {@link Test}

      diff --git a/rsc/scripts/jsdoc/test/tutorials/incomplete/parent.json b/rsc/scripts/jsdoc/test/tutorials/incomplete/parent.json deleted file mode 100644 index f2e4765a..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/incomplete/parent.json +++ /dev/null @@ -1 +0,0 @@ -{"title": "missing child tutorial", "children": ["child"]} diff --git a/rsc/scripts/jsdoc/test/tutorials/src/x.js b/rsc/scripts/jsdoc/test/tutorials/src/x.js deleted file mode 100644 index 987f8f98..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/src/x.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Test {@tutorial test2} {@tutorial dupa} - * - * @class - * @tutorial test - * @tutorial jasia - */ -function Test() {} diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/constructor.md b/rsc/scripts/jsdoc/test/tutorials/tutorials/constructor.md deleted file mode 100644 index 2f181f08..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/constructor.md +++ /dev/null @@ -1 +0,0 @@ -This tutorial has a tricksy name to make sure we are not loading Array.constructor or Object.constructor. diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/multiple.json b/rsc/scripts/jsdoc/test/tutorials/tutorials/multiple.json deleted file mode 100644 index 994d8655..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/multiple.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "test2": { - "title": "Test 2", - "children": ["test3", "test6"] - }, - "test3": { - "title": "Test 3", - "children": { - "test4": {"title": "Test 4"} - } - } -} diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test.html b/rsc/scripts/jsdoc/test/tutorials/tutorials/test.html deleted file mode 100644 index aa4a4ff9..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test.html +++ /dev/null @@ -1,3 +0,0 @@ -

      Test.html

      - -

      {@link Test}

      diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test.json b/rsc/scripts/jsdoc/test/tutorials/tutorials/test.json deleted file mode 100644 index d894f21e..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test.json +++ /dev/null @@ -1 +0,0 @@ -{"title": "Test tutorial", "children": ["test2"]} diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test2.markdown b/rsc/scripts/jsdoc/test/tutorials/tutorials/test2.markdown deleted file mode 100644 index 09510c03..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test2.markdown +++ /dev/null @@ -1 +0,0 @@ -# test2.markdown diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test3.htm b/rsc/scripts/jsdoc/test/tutorials/tutorials/test3.htm deleted file mode 100644 index 8eac0524..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test3.htm +++ /dev/null @@ -1,3 +0,0 @@ -

      Test3.html

      - -

      {@link Test}

      diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test4.md b/rsc/scripts/jsdoc/test/tutorials/tutorials/test4.md deleted file mode 100644 index 0be836ad..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test4.md +++ /dev/null @@ -1 +0,0 @@ -# test4.md diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test5.txt b/rsc/scripts/jsdoc/test/tutorials/tutorials/test5.txt deleted file mode 100644 index 1769f0de..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test5.txt +++ /dev/null @@ -1 +0,0 @@ -Should not be included as a tutorial. diff --git a/rsc/scripts/jsdoc/test/tutorials/tutorials/test6.xml b/rsc/scripts/jsdoc/test/tutorials/tutorials/test6.xml deleted file mode 100644 index 1c489be3..00000000 --- a/rsc/scripts/jsdoc/test/tutorials/tutorials/test6.xml +++ /dev/null @@ -1 +0,0 @@ -

      test 6 - has no metadata

      diff --git a/src/application/config/config.php b/src/application/config/config.php index 92e7a5bd..afe513cd 100644 --- a/src/application/config/config.php +++ b/src/application/config/config.php @@ -1,7 +1,21 @@ $this->lang->line('appointment_not_found'), 'message_text' => $this->lang->line('appointment_does_not_exist_in_db'), 'message_icon' => $this->config->item('base_url') - . 'assets/images/error.png', + . 'assets/img/error.png', 'company_name' => $company_name ); $this->load->view('appointments/message', $view); diff --git a/src/application/language/chinese/index.html b/src/application/language/chinese/index.html new file mode 100644 index 00000000..c942a79c --- /dev/null +++ b/src/application/language/chinese/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/src/application/language/chinese/migration_lang.php b/src/application/language/chinese/migration_lang.php new file mode 100644 index 00000000..f17530f0 --- /dev/null +++ b/src/application/language/chinese/migration_lang.php @@ -0,0 +1,13 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/src/application/language/dutch/migration_lang.php b/src/application/language/dutch/migration_lang.php new file mode 100644 index 00000000..f17530f0 --- /dev/null +++ b/src/application/language/dutch/migration_lang.php @@ -0,0 +1,13 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/src/application/language/french/migration_lang.php b/src/application/language/french/migration_lang.php new file mode 100644 index 00000000..f17530f0 --- /dev/null +++ b/src/application/language/french/migration_lang.php @@ -0,0 +1,13 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/src/application/language/japanese/migration_lang.php b/src/application/language/japanese/migration_lang.php new file mode 100644 index 00000000..f17530f0 --- /dev/null +++ b/src/application/language/japanese/migration_lang.php @@ -0,0 +1,13 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/src/application/language/polish/migration_lang.php b/src/application/language/polish/migration_lang.php new file mode 100644 index 00000000..f17530f0 --- /dev/null +++ b/src/application/language/polish/migration_lang.php @@ -0,0 +1,13 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/src/application/language/spanish/migration_lang.php b/src/application/language/spanish/migration_lang.php new file mode 100644 index 00000000..f17530f0 --- /dev/null +++ b/src/application/language/spanish/migration_lang.php @@ -0,0 +1,13 @@ +config->base_url(); ?>assets/images/favicon.ico"> + href="config->base_url(); ?>assets/img/favicon.ico"> config->base_url(); ?>assets/images/favicon.ico"> + href="config->base_url(); ?>assets/img/favicon.ico">