├── .gitignore ├── package.json ├── bios ├── buzz_aldrin.txt ├── neil_armstrong.txt ├── alan_bean.txt ├── pete_conrad.txt ├── edgar_mitchell.txt ├── harrison_schmitt.txt ├── charles_duke.txt ├── alan_shepard.txt ├── james_irwin.txt ├── john_young.txt ├── david_scott.txt └── eugene_cernan.txt ├── docs ├── main.css ├── corpus.json └── index.html ├── styles └── main.css ├── templates └── index.html.erb ├── README.md ├── src ├── wrapper.js └── main.js ├── Rakefile └── lunr.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moonwalk", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "webpack": "1.13.*", 6 | "json-loader": "0.5.*", 7 | "lunr": "2.3.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /bios/buzz_aldrin.txt: -------------------------------------------------------------------------------- 1 | Aldrin was one of the third group of astronauts named by NASA in October 1963. On November 11, 1966, he and command pilot James Lovell were launched into space in the Gemini 12 spacecraft on a 4-day flight, which brought the Gemini program to a successful close. Aldrin established a new record for extravehicular activity (EVA), spending 5-1/2 hours outside the spacecraft. He served as lunar module pilot for Apollo 11, July 16-24, 1969, the first manned lunar landing mission. Aldrin followed Neil Armstrong onto the lunar surface on July 20, 1969, completing a 2-hour and 15 minute lunar EVA. In July 1971, Aldrin resigned from NASA. Aldrin has logged 289 hours and 53 minutes in space, of which, 7 hours and 52 minutes were spent in EVA. 2 | -------------------------------------------------------------------------------- /docs/main.css: -------------------------------------------------------------------------------- 1 | .content { 2 | font-family: sans-serif; 3 | max-width: 800px; 4 | width: 100%; 5 | margin: 0 auto; 6 | } 7 | 8 | #search-form { 9 | width: 80%; 10 | margin: 0 auto; 11 | } 12 | 13 | #search-form input { 14 | display: block; 15 | width: 100%; 16 | padding: 0.4em; 17 | border: 1px solid #ccc; 18 | font-size: 1.4em; 19 | } 20 | 21 | #search-form .controls { 22 | margin: 1em auto; 23 | } 24 | 25 | #search-form .query-error { 26 | font-size: 0.8em; 27 | color: red; 28 | } 29 | 30 | article { 31 | border-bottom: 1px solid #ccc; 32 | } 33 | 34 | article header h2 { 35 | text-transform: capitalize; 36 | } 37 | 38 | article section p { 39 | line-height: 1.6em; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /styles/main.css: -------------------------------------------------------------------------------- 1 | .content { 2 | font-family: sans-serif; 3 | max-width: 800px; 4 | width: 100%; 5 | margin: 0 auto; 6 | } 7 | 8 | #search-form { 9 | width: 80%; 10 | margin: 0 auto; 11 | } 12 | 13 | #search-form input { 14 | display: block; 15 | width: 100%; 16 | padding: 0.4em; 17 | border: 1px solid #ccc; 18 | font-size: 1.4em; 19 | } 20 | 21 | #search-form .controls { 22 | margin: 1em auto; 23 | } 24 | 25 | #search-form .query-error { 26 | font-size: 0.8em; 27 | color: red; 28 | } 29 | 30 | article { 31 | border-bottom: 1px solid #ccc; 32 | } 33 | 34 | article header h2 { 35 | text-transform: capitalize; 36 | } 37 | 38 | article section p { 39 | line-height: 1.6em; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /templates/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 |
    15 | <% bios.each do |bio| %> 16 |
  1. 17 |
    18 |
    19 |

    <%= bio.name %>

    20 |
    21 | 22 |
    23 |

    <%= bio.body %>

    24 |
    25 |
    26 |
  2. 27 | <% end %> 28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /bios/neil_armstrong.txt: -------------------------------------------------------------------------------- 1 | As a research pilot at NASA’s Flight Research Center, Edwards, California, Armstrong was a project pilot on many pioneering high speed aircraft, including the well known, 4000-mph X-15. He flew more than 200 different models of aircraft, including jets, rockets, helicopters and gliders. Armstrong transferred to astronaut status in 1962. He was assigned as command pilot for the Gemini 8 mission. Gemini 8 was launched on March 16, 1966, and Armstrong performed the first successful docking of two vehicles in space. As spacecraft commander for Apollo 11, the first manned lunar landing mission, Armstrong gained the distinction of being the first man to land a craft on the moon and first to step on its surface. Armstrong subsequently held the position of Deputy Associate Administrator for Aeronautics, NASA Headquarters, Washington, D.C. In this position, he was responsible for the coordination and management of overall NASA research and technology work related to aeronautics. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Moonwalkers 2 | 3 | A demo site to show off some features of Lunr 2. 4 | 5 | Short bios on every person to have walked on the moon are indexed and made searchable by Lunr. 6 | 7 | ## Features 8 | 9 | * Search term highlighting 10 | * More advances query capabilities 11 | * Improved searching performance 12 | * Smaller index size 13 | 14 | ## Usage 15 | 16 | This is intended as a demo only, and the site itself is quite basic. The source should give some pointers in using Lunr 2, more comprehensive documentation and guides will be made available before the full release of Lunr 2. 17 | 18 | ### Building an Index 19 | 20 | In Lunr 2 all search indexes are static and immutable. In this site the index is built ahead of time using the script in `build-index`. 21 | 22 | ### Searching the Index 23 | 24 | The basic search interface is largely unchanged from previous versions of Lunr, the details of searching can be seen in `src/main.js`. 25 | 26 | ### Highlighting Results 27 | 28 | The index includes the positions of all terms, and this data is used by `src/wrapper.js` to highlight search results. 29 | 30 | ## Building 31 | 32 | The build is automated using rake, to re-create the site run `rake` from the project directory. 33 | -------------------------------------------------------------------------------- /bios/alan_bean.txt: -------------------------------------------------------------------------------- 1 | Alan Bean was one of the third group of astronauts named by NASA in October 1963. He served as backup astronaut for the Gemini 10 and Apollo 9 missions. Captain Bean was lunar module pilot on Apollo 12, mans second lunar landing. In November 1969, Captain Bean and Captain Pete Conrad landed in the moons Ocean of Stormsafter a flight of some 250,000 miles. They explored the lunar surface, deployed several lunar surface experiments, and installed the first nuclear power generator station on the moon to provide the power source. Captain Richard Gordon remained in lunar orbit photographing landing sites for future missions. Captain Bean was spacecraft commander of Skylab Mission II (SL-3), July 29 to September 25, 1973. With him on the 59-day, 24,400,000 mile world record setting flight were scientist-astronaut Dr. Owen K. Garriott and Marine Corps Lieutenant Colonel Jack R. Lousma. Mission II accomplished 150% of its pre-mission forecast goals. On his next assignment, Captain Bean was backup spacecraft commander of the United States flight crew for the joint American-Russian Apollo-Soyuz Test Project. Captain Bean has logged 1,671 hours and 45 minutes in spaceof which 10 hours and 26 minutes were spent in EVAs on the moon and in earth orbit. 2 | -------------------------------------------------------------------------------- /bios/pete_conrad.txt: -------------------------------------------------------------------------------- 1 | In September of 1962, Mr. Conrad was selected as an astronaut by NASA. His first flight was Gemini V, which established the space endurance record and placed the United States in the lead for man-hours in space. As commander of Gemini XI, Mr. Conrad helped to set a world's altitude record. He then served as commander of Apollo XII, the second lunar landing. On Mr. Conrad's final mission, he served as commander of Skylab II, the first United States Space Station. In December 1973, after serving 20 years (11 of which were as an astronaut in the space program), Mr. Conrad retired from the U.S. Navy to accept a position as Vice President - Operations and Chief Operating Office of American Television and Communications Corporation (ATC). At ATC, he was responsible for both the operation of existing systems and the national development of new cable television systems. In 1976, he resigned from ATC to accept the position of Vice President and consultant to McDonnell Douglas Corporation. In 1978, he became Vice President of marketing and was responsible for all commercial and military sales for Douglas Aircraft Company. Mr. Conrad then became Senior Vice President-Marketing in 1980. He was appointed as Senior Vice President Marketing and Product Support in 1982 and 1984, was named Staff Vice President of International Business Development for McDonnell Douglas Corporation. 2 | -------------------------------------------------------------------------------- /bios/edgar_mitchell.txt: -------------------------------------------------------------------------------- 1 | Mitchell was a member of Group 5, selected for astronaut training in April 1966. He served as a member of the astronaut support crew for Apollo 9 and as backup lunar module pilot for Apollo 10. On January 31, 1971, serving as lunar module pilot, Dr. Edgar Mitchell, then a U.S. Navy Captain, embarked on a journey through outer space of some 500,000 miles that resulted in becoming the sixth man to walk on the moon. That historic journey terminated safely nine days later on February 9, 1971 and was made in the company of two other men of valor Admiral Alan Shepard and Colonel Stuart Roosa. Maneuvering their lunar module, Antares, to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to Earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of color TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations. In completing his first space flight, Mitchell logged a total of 216 hours and 42 minutes in space. He was subsequently designated to serve as backup lunar module pilot for Apollo 16. 2 | -------------------------------------------------------------------------------- /bios/harrison_schmitt.txt: -------------------------------------------------------------------------------- 1 | Dr. Schmitt was selected as a scientist-astronaut by NASA in June 1965. He later completed a 53-week course in flight training at Williams Air Force Base, Arizona. In addition to training for future manned space flights. He was instrumental in providing Apollo flight crews with detailed instruction in lunar navigation, geology, and feature recognition. Schmitt also assisted in the integration of scientific activities into the Apollo lunar missions and participated in research activities requiring geologic, petrographic, and stratigraphic analyses of samples returned from the moon by Apollo missions. On his first journey into space, Dr. Schmitt occupied the lunar module pilot seat for Apollo 17 -- the last scheduled manned Apollo mission to the United States --which commenced at 11:33 p.m. (CST), December 6, 1972, and concluded on December 19, 1972. He was accompanied on the voyage of the command module "America" and the lunar module "Challenger" by Eugene Cernan (spacecraft commander) and Ronald Evans (command module pilot). In maneuvering "Challenger" to a landing at Taurus-Littrow, which is located on the southeast edge of Mare Serenitatis, Schmitt and Cernan activated a base of operations facilitating their completion of three days of exploration. This last Apollo mission to the moon for the United States broke several records set by previous flights and include: longest manned lunar landing flight (301 hours, 51 minutes); longest lunar surface extravehicular activities (22 hours, 4 minutes); largest lunar sample return (an estimated 115 Kg, 249 lbs); and longest time in lunar orbit (147 hours, 48 minutes). Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 mile from the target point and 4.3 miles from the prime recovery ship, USS TICONDEROGA. 2 | -------------------------------------------------------------------------------- /bios/charles_duke.txt: -------------------------------------------------------------------------------- 1 | Duke was one of the 19 astronauts selected by NASA in April 1966. He served as member of the astronaut support crew for the Apollo 10 flight. He was CAPCOM for Apollo 11, the first landing on the Moon and he served as backup lunar module pilot on Apollo 13. Duke served as lunar module pilot of Apollo 16, April 16-27, 1972. He was accompanied on the fifth manned lunar landing mission by John W. Young (spacecraft commander) and Thomas K. Mattingly II (command module pilot). Apollo 16 was the first scientific expedition to inspect, survey, and sample materials and surface features in the Descartes region of the rugged lunar highlands. Duke and Young commenced their record setting lunar surface stay of 71 hours and 14 minutes by maneuvering the lunar module "Orion" to a landing on the rough Cayley Plains. In three subsequent excursions onto the lunar surface, they each logged 20 hours and 15 minutes in extravehicular activities involving the emplacement and activation of scientific equipment and experiments, the collection of nearly 213 pounds of rock and soil samples, and the evaluation and use of Rover-2 over the roughest and blockiest surface yet encountered on the moon. Other Apollo 16 achievements included the largest payload placed in lunar orbit (76, 109 pounds); first cosmic ray detector deployed on lunar surface; first lunar observatory with the far UV camera; and longest in-flight EVA from a command module during transearth coast (1 hour and 13 minutes). The latter feat was accomplished by Mattingly when he ventured out to "Casper's" SIM-bay for the retrieval of vital film cassettes from the panoramic and mapping cameras. Apollo 16 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS TICONDEROGA. With the completion of his first space flight, Duke has logged 265 hours in space and over 21 hours of extra vehicular activity. Duke also served as backup lunar module pilot for Apollo 17. 2 | -------------------------------------------------------------------------------- /src/wrapper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the location of a match within a 3 | * larger string. Extracted from a lunr.Index~Result. 4 | * 5 | * @typedef {number[]} MatchLocation 6 | * @property {number} 0 - Starting index of the match 7 | * @property {number} 1 - Length of the match 8 | */ 9 | 10 | /** 11 | * Highlights text within a dom element. 12 | * 13 | * Specifically this is designed to work with the output 14 | * positions of terms returned from a lunr search. 15 | * 16 | * @param {HTMLElement} element - the element that contains text to highlight. 17 | * @param {MatchLocation[]} matches - the list of matches to highlight. 18 | */ 19 | module.exports = function (element, matches) { 20 | 21 | var nodeFilter = { 22 | acceptNode: function (node) { 23 | if (/^[\t\n\r ]*$/.test(node.nodeValue)) { 24 | return NodeFilter.FILTER_SKIP 25 | } 26 | return NodeFilter.FILTER_ACCEPT 27 | } 28 | } 29 | 30 | var index = 0, 31 | matches = matches.sort(function (a, b) { return a[0] - b[0] }).slice(), 32 | previousMatch = [-1, -1] 33 | match = matches.shift(), 34 | walker = document.createTreeWalker( 35 | element, 36 | NodeFilter.SHOW_TEXT, 37 | nodeFilter, 38 | false 39 | ) 40 | 41 | while (node = walker.nextNode()) { 42 | if (match == undefined) break 43 | if (match[0] == previousMatch[0]) continue 44 | 45 | var text = node.textContent, 46 | nodeEndIndex = index + node.length; 47 | 48 | if (match[0] < nodeEndIndex) { 49 | var range = document.createRange(), 50 | tag = document.createElement('mark'), 51 | rangeStart = match[0] - index, 52 | rangeEnd = rangeStart + match[1]; 53 | 54 | tag.dataset.rangeStart = rangeStart 55 | tag.dataset.rangeEnd = rangeEnd 56 | 57 | range.setStart(node, rangeStart) 58 | range.setEnd(node, rangeEnd) 59 | range.surroundContents(tag) 60 | 61 | index = match[0] + match[1] 62 | 63 | // the next node will now actually be the text we just wrapped, so 64 | // we need to skip it 65 | walker.nextNode() 66 | previousMatch = match 67 | match = matches.shift() 68 | } else { 69 | index = nodeEndIndex 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /bios/alan_shepard.txt: -------------------------------------------------------------------------------- 1 | Rear Admiral Shepard was one of the Mercury astronauts named by NASA in April 1959, and he holds the distinction of being the first American to journey into space. On May 5, 1961, in the Freedom 7 spacecraft, he was launched by a Redstone vehicle on a ballistic trajectory suborbital flight--a flight which carried him to an altitude of 116 statute miles and to a landing point 302 statute miles down the Atlantic Missile Range. In 1963, he was designated Chief of the Astronaut Office with responsibility for monitoring the coordination, scheduling, and control of all activities involving NASA astronauts. This included monitoring the development and implementation of effective training programs to assure the flight readiness of available pilot/non-pilot personnel for assignment to crew positions on manned space flights; furnishing pilot evaluations applicable to the design, construction, and operations of spacecraft systems and related equipment; and providing qualitative scientific and engineering observations to facilitate overall mission planning, formulation of feasible operational procedures, and selection and conduct of specific experiments for each flight. He was restored to full flight status in May 1969, following corrective surgery for an inner ear disorder. Shepard made his second space flight as spacecraft commander on Apollo 14, January 31 - February 9, 1971. He was accompanied on man's third lunar landing mission by Stuart A. Roosa, command module pilot, and Edgar D. Mitchell, lunar module pilot. Maneuvering their lunar module, "Antares," to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of colored TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations. 2 | -------------------------------------------------------------------------------- /bios/james_irwin.txt: -------------------------------------------------------------------------------- 1 | Colonel Irwin was one of the 19 astronauts selected by NASA in April 1966. He was crew commander of lunar module (LTA-8)-this vehicle finished the first series of thermal vacuum tests on June 1, 1968. He also served as a member of the astronaut support crew for Apollo 10 and as backup lunar module pilot for the Apollo 12 flight. Irwin served as lunar module pilot for Apollo, July 26 to August 7, 1971. His companions on the flight were David R. Scott, spacecraft commander and Alfred M. Worden, command module pilot. Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, "Falcon", remained on the lunar surface for 66 hours, 54 minutes-setting a new record for lunar surface stay time-and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using "Rover-l" to transport themselves and their equipment along portions of Hadley Rille and the Apinnine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected approximately 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised in color using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements included: largest payloads ever placed in earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device, mounted on Rover 1; first subsatellite launched in lunar orbit; and first extravehicular activity (EVA) from a command module during transearth coast. The latter feat was accomplished by Worden during three excursions to "Endeavour's" SIM bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific splashdown and subsequent recovery by the USS OKINAWA. 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'json' 3 | require 'erb' 4 | require 'open3' 5 | require 'webrick' 6 | 7 | class Template 8 | Bio = Struct.new(:id, :name, :body) 9 | 10 | def self.render(corpus_path, template_path) 11 | new(corpus_path, template_path).render 12 | end 13 | 14 | def initialize(corpus_path, template_path) 15 | @corpus_path = corpus_path 16 | @template_path = template_path 17 | end 18 | 19 | def bios 20 | corpus.map do |attrs| 21 | Bio.new(*attrs.values_at('id', 'name', 'body')) 22 | end 23 | end 24 | 25 | def render 26 | b = binding 27 | template.result(b) 28 | end 29 | 30 | private 31 | 32 | attr_reader :corpus_path, :template_path 33 | 34 | def corpus 35 | @corpus ||= JSON.parse(File.read(corpus_path)) 36 | end 37 | 38 | def template 39 | @template ||= ERB.new(File.read(template_path)) 40 | end 41 | end 42 | 43 | directory "docs" 44 | 45 | file 'docs/corpus.json' => ['docs', *Rake::FileList['bios/*.txt']] do |t| 46 | corpus = t.sources.grep(/\.txt$/) 47 | .map do |path| 48 | { 49 | id: path.pathmap('%n'), 50 | name: path.pathmap('%n').gsub('_', ' '), 51 | body: File.read(path), 52 | } 53 | end 54 | 55 | File.open(t.name, 'w') do |f| 56 | f << JSON.generate(corpus) 57 | end 58 | end 59 | 60 | file 'docs/index.html' => ['docs/corpus.json', 'templates/index.html.erb'] do |t| 61 | File.open(t.name, 'w') do |f| 62 | f << Template.render(*t.sources) 63 | end 64 | end 65 | 66 | file 'docs/index.json' => ['docs/corpus.json'] do |t| 67 | Open3.popen2('./build-index') do |stdin, stdout, wt| 68 | IO.copy_stream(t.source, stdin) 69 | stdin.close 70 | IO.copy_stream(stdout, t.name) 71 | end 72 | end 73 | 74 | file 'docs/index.js' => [*Rake::FileList['src/*.js']] do |t| 75 | sh "./node_modules/.bin/webpack src/main.js #{t.name}" 76 | end 77 | 78 | file 'docs/main.css' => ['docs', 'styles/main.css'] do |t| 79 | cp 'styles/main.css', 'docs/main.css' 80 | end 81 | 82 | task :default => ['docs/index.json', 'docs/index.html', 'docs/index.js', 'docs/main.css'] 83 | 84 | task :server do 85 | WEBrick::HTTPServer.new(:Host => '0.0.0.0', :Port => 8000, :DocumentRoot => Dir.pwd + "/docs").start 86 | end 87 | 88 | task :clean do 89 | rm_rf 'docs' 90 | end 91 | -------------------------------------------------------------------------------- /bios/john_young.txt: -------------------------------------------------------------------------------- 1 | In September 1962, Young was selected as an astronaut. He is the first person to fly in space six times from earth, and seven times counting his lunar liftoff. The first flight was with Gus Grissom in Gemini 3, the first manned Gemini mission, on March 23, 1965. This was a complete end-to-end test of the Gemini spacecraft, during which Gus accomplished the first manual change of orbit altitude and plane and the first lifting reentry, and Young operated the first computer on a manned spacecraft. On Gemini 10, July 18-21, 1966, Young, as Commander, and Mike Collins, as Pilot, completed a dual rendezvous with two separate Agena target vehicles. While Young flew close formation on the second Agena, Mike Collins did an extravehicular transfer to retrieve a micro meteorite detector from that Agena. On his third flight, May 18-26, 1969, Young was Command Module Pilot of Apollo 10. Tom Stafford and Gene Cernan were also on this mission which orbited the Moon, completed a lunar rendezvous, and tracked proposed lunar landing sites. His fourth space flight, Apollo 16, April 16-27, 1972, was a lunar exploration mission, with Young as Spacecraft Commander, and Ken Mattingly and Charlie Duke. Young and Duke set up scientific equipment and explored the lunar highlands at Descartes. They collected 200 pounds of rocks and drove over 16 miles in the lunar rover on three separate geology traverses. Young’s fifth flight was as Spacecraft Commander of STS-1, the first flight of the Space Shuttle, April 12-14, 1981, with Bob Crippen as Pilot. The 54-1/2 hour, 36-orbit mission verified Space Shuttle systems performance during launch, on orbit, and entry. Tests of the Orbiter Columbia included evaluation of mechanical systems including the payload bay doors, the attitude and maneuvering rocket thrusters, guidance and navigation systems, and Orbiter/crew compatibility. One hundred and thirty three of the mission’s flight test objectives were accomplished. The Orbiter Columbia was the first manned spaceship tested during ascent, on orbit, and entry without benefit of previous unmanned missions. Columbia was also the first winged reentry vehicle to return from space to a runway landing. It weighed about 98 tons as Young landed it on the dry lakebed at Edwards Air Force Base, California. Young’s sixth flight was as Spacecraft Commander of STS-9, the first Spacelab mission, November 28-December 8, 1983, with Pilot Brewster Shaw, Mission Specialists Bob Parker and Owen Garriott, and Payload Specialists Byron Lichtenberg of the USA and Ulf Merbold of West Germany. The mission successfully completed all 94 of its flight test objectives. For ten days the 6-man crew worked 12-hour shifts around-the-clock, performing more than 70 experiments in the fields of atmospheric physics, Earth observations, space plasma physics, astronomy and solar physics, materials processing and life sciences. The mission returned more scientific and technical data than all the previous Apollo and Skylab missions put together. The Spacelab was brought back for re-use, so that Columbia weighed over 110 tons as Young landed the spaceship at Edwards Air Force Base, California. 2 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | var json = require('json!./../docs/index.json'), 2 | corpus = require('json!./../docs/corpus.json'), 3 | lunr = require('lunr'), 4 | wrapper = require('./wrapper.js') 5 | 6 | var idx = lunr.Index.load(json) 7 | 8 | var documents = corpus.reduce(function (memo, doc) { 9 | memo[doc.id] = doc 10 | return memo 11 | }, {}) 12 | 13 | window.corpus = corpus 14 | window.idx = idx 15 | window.lunr = lunr 16 | 17 | window.search = function (q) { 18 | console.time('search: ' + q) 19 | var results = idx.search(q) 20 | console.timeEnd('search: ' + q) 21 | return results 22 | } 23 | 24 | var buildSearchResult = function (doc) { 25 | var li = document.createElement('li'), 26 | article = document.createElement('article'), 27 | header = document.createElement('header'), 28 | section = document.createElement('section'), 29 | h2 = document.createElement('h2'), 30 | p = document.createElement('p') 31 | 32 | h2.dataset.field = 'name' 33 | h2.textContent = doc.name 34 | 35 | p.dataset.field = 'body' 36 | p.textContent = doc.body 37 | 38 | li.appendChild(article) 39 | article.appendChild(header) 40 | article.appendChild(section) 41 | header.appendChild(h2) 42 | section.appendChild(p) 43 | 44 | return li 45 | } 46 | 47 | var displayQueryError = function (queryText, error) { 48 | var message = document.createElement('p'), 49 | container = document.querySelector('.query-error') 50 | 51 | message.classList.add('message') 52 | message.textContent = error.message 53 | 54 | container.appendChild(message) 55 | } 56 | 57 | var clearQueryError = function () { 58 | var container = document.querySelector('.query-error') 59 | 60 | while (container.firstChild) { 61 | container.removeChild(container.firstChild) 62 | } 63 | } 64 | 65 | var searchForm = document.querySelector('#search-form'), 66 | searchField = searchForm.querySelector('input') 67 | 68 | searchForm.addEventListener('reset', function (event) { 69 | clearQueryError() 70 | 71 | var ol = document.querySelector('ol') 72 | 73 | while (ol.firstChild) { 74 | ol.removeChild(ol.firstChild) 75 | } 76 | 77 | Object.keys(documents).forEach(function (id) { 78 | var doc = documents[id], 79 | li = buildSearchResult(doc) 80 | 81 | ol.appendChild(li) 82 | }) 83 | }) 84 | 85 | searchForm.addEventListener('submit', function (event) { 86 | event.preventDefault() 87 | clearQueryError() 88 | 89 | var query = searchField.value, 90 | results = undefined, 91 | ol = document.querySelector('ol') 92 | 93 | try { 94 | results = idx.search(query) 95 | } catch(e) { 96 | if (e instanceof lunr.QueryParseError) { 97 | displayQueryError(query, e) 98 | return 99 | } else { 100 | throw e 101 | } 102 | } 103 | 104 | while (ol.firstChild) { 105 | ol.removeChild(ol.firstChild) 106 | } 107 | 108 | results.forEach(function (result) { 109 | var doc = documents[result.ref], 110 | li = buildSearchResult(doc) 111 | 112 | Object.keys(result.matchData.metadata).forEach(function (term) { 113 | Object.keys(result.matchData.metadata[term]).forEach(function (fieldName) { 114 | var field = li.querySelector('[data-field=' + fieldName + ']'), 115 | positions = result.matchData.metadata[term][fieldName].position 116 | 117 | wrapper(field, positions) 118 | }) 119 | }) 120 | 121 | ol.appendChild(li) 122 | }) 123 | }) 124 | -------------------------------------------------------------------------------- /bios/david_scott.txt: -------------------------------------------------------------------------------- 1 | Scott was one of the third group of astronauts named by NASA in October 1963. On March 16, 1966, he and command pilot Neil Armstrong were launched into space on the Gemini 8 mission--a flight originally scheduled to last three days but terminated early due to a malfunctioning thruster. The crew performed the first successful docking of two vehicles in space and demonstrated great piloting skill in overcoming the thruster problem and bringing the spacecraft to a safe landing. Scott served as command module pilot for Apollo 9, March 3-13, 1969. This was the third manned flight in the Apollo series, the second to be launched by a Saturn V, and the first to complete a comprehensive earth-orbital qualification and verification test of a "fully configured Apollo spacecraft." The ten-day flight provided vital information previously not available on the operational performance, stability, and reliability of lunar module propulsion and life support systems. Highlight of this evaluation was completion of a critical lunar-orbit rendezvous simulation and subsequent docking, initiated by James McDivitt and Russell Schweickart from within the lunar module at a separation distance which exceeded 100 miles from the command/service module piloted by Scott. The crew also demonstrated and confirmed the operational feasibility of crew transfer and extravehicular activity techniques and equipment, with Schweickart completing a 46-minute EVA outside the lunar module. During this period, Dave Scott completed a 1-hour stand-up EVA in the open command module hatch photographing Schweickart's activities and also retrieving thermal samples from the command module exterior. Apollo 9 splashed down less than four miles from the helicopter carrier USS GUADALCANAL. In his next assignment, Scott was designated backup spacecraft commander for Apollo 12. He made his third space flight as spacecraft commander of Apollo 15, July 26 - August 7, 1971. His companions on the flight were Alfred M. Worden (command module pilot) and James B. Irwin (lunar module pilot). Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, "Falcon," remained on the lunar surface for 66 hours and 54 minutes (setting a new record for lunar surface stay time) and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using "Rover-1" to transport themselves and their equipment along portions of Hadley Rille and the Apennine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements include: largest payloads ever placed into earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device (mounted on Rover-1); first subsatellite launched in lunar orbit; and first extravehicular (EVA) from a command module during transearth coast. The latter feat performed by Worden during three excursions to "Endeavour's" SIM-bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS OKINAWA. 2 | -------------------------------------------------------------------------------- /bios/eugene_cernan.txt: -------------------------------------------------------------------------------- 1 | Captain Cernan was one of fourteen astronauts selected by NASA in October 1963. He occupied the pilot seat alongside of command pilot Tom Stafford on the Gemini IX mission. During this 3-day flight which Began on June 3, 1966, the spacecraft achieved a circular orbit of 161 statute miles; the crew used three different techniques to effect rendezvous with the previously launched Augmented Target Docking Adapter; and Cernan, the second American to walk in space, logged two hours and ten minutes outside the spacecraft in extravehicular activities. The flight ended after 72 hours and 20 minutes with a perfect re-entry and recovery as Gemini IX landed within 1-1/2 miles of the prime recovery ship USS WASP and 3/8 of a mile from the predetermined target. Cernan subsequently served as backup pilot for Gemini 12 and as backup lunar module pilot for Apollo 7. On his second space flight, he was lunar module pilot of Apollo 10, May 18-26, 1969, the first comprehensive lunar-orbital qualification and verification flight test of an Apollo lunar module. He was accompanied on the 248,000 nautical sojourn to the moon by Thomas P. Stafford (spacecraft commander) and John W. Young (commander module pilot). In accomplishing all of the assigned objectives of this mission, Apollo 10 confirmed the operations performance, stability, and reliability of the command/service module and lunar module configuration during trans-lunar coast, lunar orbit insertion, and lunar module separation and descent to within 8 nautical miles of the lunar surface. The latter maneuver involved employing all but the final minutes of the technique prescribed for use in an actual lunar landing, and allowed critical evaluations of the lunar module propulsions systems and rendezvous of the landing radar devices in subsequent rendezvous and re-docking maneuvers. In addition to demonstrating that man could navigate safely and accurately in the moon's gravitational fields, Apollo 10 photographed and mapped tentative landing sites for future missions. Cernan's next assignment was backup spacecraft commander for Apollo 14. He made his third space flight as spacecraft commander of Apollo 17--the last scheduled manned mission to the moon for the United States--which commenced at 11:33 P.M. (CST), December 6, 1972, with the first manned nighttime launch, and concluded on December 19, 1972. With him on the voyage of the command module "America" and the lunar module "Challenger" were Ronald Evans (command module pilot) and Harrison H. (Jack) Schmitt (lunar module pilot). In maneuvering "Challenger" to a landing at Taurus-Littrow, located on the southeast edge of Mare Serenitatis, Cernan and Schmitt activated a base of operations from which they completed three highly successful excursions to the nearby craters and the Taurus mountains, making the Moon their home for over three days. This last mission to the moon established several new records for manned space flight that include: longest manned lunar landing flight (301 hours 51 minutes); longest lunar surface extravehicular activities (22 hours 6 minutes); largest lunar sample return (an estimated 115 kg (249 lbs.); and longest time in lunar orbit (147 hours 48 minutes). While Cernan and Schmitt conducted activities on the lunar surface, Evans remained in lunar orbit aboard the "America" completing assigned work tasks requiring geological observations, handheld photography of specific targets, and the control of cameras and other highly sophisticated scientific equipment carried in the command module SIM-bay. Evans also completed a 1-hour, 6-minute extravehicular activity on the transearth coast phase of the return flight, successfully retrieving three camera cassettes and completing a personal inspection of the equipment bay area. Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 miles from the target point and 4.3 miles form the prime recovery ship USS TICONDEROGA. Captain Cernan was the second American to have walked in space having spanned the circumference of the world twice in a little more than 2-1/2 hours. He was one of the two men to have flown to the moon on two occasions, and as commander of the last mission to the moon, Apollo 17, had the privilege and distinction of being the last man to have left his footprints on the surface of the moon. 2 | -------------------------------------------------------------------------------- /docs/corpus.json: -------------------------------------------------------------------------------- 1 | [{"id":"alan_bean","name":"alan bean","body":"Alan Bean was one of the third group of astronauts named by NASA in October 1963. He served as backup astronaut for the Gemini 10 and Apollo 9 missions. Captain Bean was lunar module pilot on Apollo 12, mans second lunar landing. In November 1969, Captain Bean and Captain Pete Conrad landed in the moons Ocean of Stormsafter a flight of some 250,000 miles. They explored the lunar surface, deployed several lunar surface experiments, and installed the first nuclear power generator station on the moon to provide the power source. Captain Richard Gordon remained in lunar orbit photographing landing sites for future missions. Captain Bean was spacecraft commander of Skylab Mission II (SL-3), July 29 to September 25, 1973. With him on the 59-day, 24,400,000 mile world record setting flight were scientist-astronaut Dr. Owen K. Garriott and Marine Corps Lieutenant Colonel Jack R. Lousma. Mission II accomplished 150% of its pre-mission forecast goals. On his next assignment, Captain Bean was backup spacecraft commander of the United States flight crew for the joint American-Russian Apollo-Soyuz Test Project. Captain Bean has logged 1,671 hours and 45 minutes in spaceof which 10 hours and 26 minutes were spent in EVAs on the moon and in earth orbit.\n"},{"id":"alan_shepard","name":"alan shepard","body":"Rear Admiral Shepard was one of the Mercury astronauts named by NASA in April 1959, and he holds the distinction of being the first American to journey into space. On May 5, 1961, in the Freedom 7 spacecraft, he was launched by a Redstone vehicle on a ballistic trajectory suborbital flight--a flight which carried him to an altitude of 116 statute miles and to a landing point 302 statute miles down the Atlantic Missile Range. In 1963, he was designated Chief of the Astronaut Office with responsibility for monitoring the coordination, scheduling, and control of all activities involving NASA astronauts. This included monitoring the development and implementation of effective training programs to assure the flight readiness of available pilot/non-pilot personnel for assignment to crew positions on manned space flights; furnishing pilot evaluations applicable to the design, construction, and operations of spacecraft systems and related equipment; and providing qualitative scientific and engineering observations to facilitate overall mission planning, formulation of feasible operational procedures, and selection and conduct of specific experiments for each flight. He was restored to full flight status in May 1969, following corrective surgery for an inner ear disorder. Shepard made his second space flight as spacecraft commander on Apollo 14, January 31 - February 9, 1971. He was accompanied on man's third lunar landing mission by Stuart A. Roosa, command module pilot, and Edgar D. Mitchell, lunar module pilot. Maneuvering their lunar module, \"Antares,\" to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of colored TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations.\n"},{"id":"buzz_aldrin","name":"buzz aldrin","body":"Aldrin was one of the third group of astronauts named by NASA in October 1963. On November 11, 1966, he and command pilot James Lovell were launched into space in the Gemini 12 spacecraft on a 4-day flight, which brought the Gemini program to a successful close. Aldrin established a new record for extravehicular activity (EVA), spending 5-1/2 hours outside the spacecraft. He served as lunar module pilot for Apollo 11, July 16-24, 1969, the first manned lunar landing mission. Aldrin followed Neil Armstrong onto the lunar surface on July 20, 1969, completing a 2-hour and 15 minute lunar EVA. In July 1971, Aldrin resigned from NASA. Aldrin has logged 289 hours and 53 minutes in space, of which, 7 hours and 52 minutes were spent in EVA.\n"},{"id":"charles_duke","name":"charles duke","body":"Duke was one of the 19 astronauts selected by NASA in April 1966. He served as member of the astronaut support crew for the Apollo 10 flight. He was CAPCOM for Apollo 11, the first landing on the Moon and he served as backup lunar module pilot on Apollo 13. Duke served as lunar module pilot of Apollo 16, April 16-27, 1972. He was accompanied on the fifth manned lunar landing mission by John W. Young (spacecraft commander) and Thomas K. Mattingly II (command module pilot). Apollo 16 was the first scientific expedition to inspect, survey, and sample materials and surface features in the Descartes region of the rugged lunar highlands. Duke and Young commenced their record setting lunar surface stay of 71 hours and 14 minutes by maneuvering the lunar module \"Orion\" to a landing on the rough Cayley Plains. In three subsequent excursions onto the lunar surface, they each logged 20 hours and 15 minutes in extravehicular activities involving the emplacement and activation of scientific equipment and experiments, the collection of nearly 213 pounds of rock and soil samples, and the evaluation and use of Rover-2 over the roughest and blockiest surface yet encountered on the moon. Other Apollo 16 achievements included the largest payload placed in lunar orbit (76, 109 pounds); first cosmic ray detector deployed on lunar surface; first lunar observatory with the far UV camera; and longest in-flight EVA from a command module during transearth coast (1 hour and 13 minutes). The latter feat was accomplished by Mattingly when he ventured out to \"Casper's\" SIM-bay for the retrieval of vital film cassettes from the panoramic and mapping cameras. Apollo 16 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS TICONDEROGA. With the completion of his first space flight, Duke has logged 265 hours in space and over 21 hours of extra vehicular activity. Duke also served as backup lunar module pilot for Apollo 17.\n"},{"id":"david_scott","name":"david scott","body":"Scott was one of the third group of astronauts named by NASA in October 1963. On March 16, 1966, he and command pilot Neil Armstrong were launched into space on the Gemini 8 mission--a flight originally scheduled to last three days but terminated early due to a malfunctioning thruster. The crew performed the first successful docking of two vehicles in space and demonstrated great piloting skill in overcoming the thruster problem and bringing the spacecraft to a safe landing. Scott served as command module pilot for Apollo 9, March 3-13, 1969. This was the third manned flight in the Apollo series, the second to be launched by a Saturn V, and the first to complete a comprehensive earth-orbital qualification and verification test of a \"fully configured Apollo spacecraft.\" The ten-day flight provided vital information previously not available on the operational performance, stability, and reliability of lunar module propulsion and life support systems. Highlight of this evaluation was completion of a critical lunar-orbit rendezvous simulation and subsequent docking, initiated by James McDivitt and Russell Schweickart from within the lunar module at a separation distance which exceeded 100 miles from the command/service module piloted by Scott. The crew also demonstrated and confirmed the operational feasibility of crew transfer and extravehicular activity techniques and equipment, with Schweickart completing a 46-minute EVA outside the lunar module. During this period, Dave Scott completed a 1-hour stand-up EVA in the open command module hatch photographing Schweickart's activities and also retrieving thermal samples from the command module exterior. Apollo 9 splashed down less than four miles from the helicopter carrier USS GUADALCANAL. In his next assignment, Scott was designated backup spacecraft commander for Apollo 12. He made his third space flight as spacecraft commander of Apollo 15, July 26 - August 7, 1971. His companions on the flight were Alfred M. Worden (command module pilot) and James B. Irwin (lunar module pilot). Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, \"Falcon,\" remained on the lunar surface for 66 hours and 54 minutes (setting a new record for lunar surface stay time) and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using \"Rover-1\" to transport themselves and their equipment along portions of Hadley Rille and the Apennine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements include: largest payloads ever placed into earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device (mounted on Rover-1); first subsatellite launched in lunar orbit; and first extravehicular (EVA) from a command module during transearth coast. The latter feat performed by Worden during three excursions to \"Endeavour's\" SIM-bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS OKINAWA.\n"},{"id":"edgar_mitchell","name":"edgar mitchell","body":"Mitchell was a member of Group 5, selected for astronaut training in April 1966. He served as a member of the astronaut support crew for Apollo 9 and as backup lunar module pilot for Apollo 10. On January 31, 1971, serving as lunar module pilot, Dr. Edgar Mitchell, then a U.S. Navy Captain, embarked on a journey through outer space of some 500,000 miles that resulted in becoming the sixth man to walk on the moon. That historic journey terminated safely nine days later on February 9, 1971 and was made in the company of two other men of valor Admiral Alan Shepard and Colonel Stuart Roosa. Maneuvering their lunar module, Antares, to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to Earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of color TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations. In completing his first space flight, Mitchell logged a total of 216 hours and 42 minutes in space. He was subsequently designated to serve as backup lunar module pilot for Apollo 16.\n"},{"id":"eugene_cernan","name":"eugene cernan","body":"Captain Cernan was one of fourteen astronauts selected by NASA in October 1963. He occupied the pilot seat alongside of command pilot Tom Stafford on the Gemini IX mission. During this 3-day flight which Began on June 3, 1966, the spacecraft achieved a circular orbit of 161 statute miles; the crew used three different techniques to effect rendezvous with the previously launched Augmented Target Docking Adapter; and Cernan, the second American to walk in space, logged two hours and ten minutes outside the spacecraft in extravehicular activities. The flight ended after 72 hours and 20 minutes with a perfect re-entry and recovery as Gemini IX landed within 1-1/2 miles of the prime recovery ship USS WASP and 3/8 of a mile from the predetermined target. Cernan subsequently served as backup pilot for Gemini 12 and as backup lunar module pilot for Apollo 7. On his second space flight, he was lunar module pilot of Apollo 10, May 18-26, 1969, the first comprehensive lunar-orbital qualification and verification flight test of an Apollo lunar module. He was accompanied on the 248,000 nautical sojourn to the moon by Thomas P. Stafford (spacecraft commander) and John W. Young (commander module pilot). In accomplishing all of the assigned objectives of this mission, Apollo 10 confirmed the operations performance, stability, and reliability of the command/service module and lunar module configuration during trans-lunar coast, lunar orbit insertion, and lunar module separation and descent to within 8 nautical miles of the lunar surface. The latter maneuver involved employing all but the final minutes of the technique prescribed for use in an actual lunar landing, and allowed critical evaluations of the lunar module propulsions systems and rendezvous of the landing radar devices in subsequent rendezvous and re-docking maneuvers. In addition to demonstrating that man could navigate safely and accurately in the moon's gravitational fields, Apollo 10 photographed and mapped tentative landing sites for future missions. Cernan's next assignment was backup spacecraft commander for Apollo 14. He made his third space flight as spacecraft commander of Apollo 17--the last scheduled manned mission to the moon for the United States--which commenced at 11:33 P.M. (CST), December 6, 1972, with the first manned nighttime launch, and concluded on December 19, 1972. With him on the voyage of the command module \"America\" and the lunar module \"Challenger\" were Ronald Evans (command module pilot) and Harrison H. (Jack) Schmitt (lunar module pilot). In maneuvering \"Challenger\" to a landing at Taurus-Littrow, located on the southeast edge of Mare Serenitatis, Cernan and Schmitt activated a base of operations from which they completed three highly successful excursions to the nearby craters and the Taurus mountains, making the Moon their home for over three days. This last mission to the moon established several new records for manned space flight that include: longest manned lunar landing flight (301 hours 51 minutes); longest lunar surface extravehicular activities (22 hours 6 minutes); largest lunar sample return (an estimated 115 kg (249 lbs.); and longest time in lunar orbit (147 hours 48 minutes). While Cernan and Schmitt conducted activities on the lunar surface, Evans remained in lunar orbit aboard the \"America\" completing assigned work tasks requiring geological observations, handheld photography of specific targets, and the control of cameras and other highly sophisticated scientific equipment carried in the command module SIM-bay. Evans also completed a 1-hour, 6-minute extravehicular activity on the transearth coast phase of the return flight, successfully retrieving three camera cassettes and completing a personal inspection of the equipment bay area. Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 miles from the target point and 4.3 miles form the prime recovery ship USS TICONDEROGA. Captain Cernan was the second American to have walked in space having spanned the circumference of the world twice in a little more than 2-1/2 hours. He was one of the two men to have flown to the moon on two occasions, and as commander of the last mission to the moon, Apollo 17, had the privilege and distinction of being the last man to have left his footprints on the surface of the moon.\n"},{"id":"harrison_schmitt","name":"harrison schmitt","body":"Dr. Schmitt was selected as a scientist-astronaut by NASA in June 1965. He later completed a 53-week course in flight training at Williams Air Force Base, Arizona. In addition to training for future manned space flights. He was instrumental in providing Apollo flight crews with detailed instruction in lunar navigation, geology, and feature recognition. Schmitt also assisted in the integration of scientific activities into the Apollo lunar missions and participated in research activities requiring geologic, petrographic, and stratigraphic analyses of samples returned from the moon by Apollo missions. On his first journey into space, Dr. Schmitt occupied the lunar module pilot seat for Apollo 17 -- the last scheduled manned Apollo mission to the United States --which commenced at 11:33 p.m. (CST), December 6, 1972, and concluded on December 19, 1972. He was accompanied on the voyage of the command module \"America\" and the lunar module \"Challenger\" by Eugene Cernan (spacecraft commander) and Ronald Evans (command module pilot). In maneuvering \"Challenger\" to a landing at Taurus-Littrow, which is located on the southeast edge of Mare Serenitatis, Schmitt and Cernan activated a base of operations facilitating their completion of three days of exploration. This last Apollo mission to the moon for the United States broke several records set by previous flights and include: longest manned lunar landing flight (301 hours, 51 minutes); longest lunar surface extravehicular activities (22 hours, 4 minutes); largest lunar sample return (an estimated 115 Kg, 249 lbs); and longest time in lunar orbit (147 hours, 48 minutes). Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 mile from the target point and 4.3 miles from the prime recovery ship, USS TICONDEROGA.\n"},{"id":"james_irwin","name":"james irwin","body":"Colonel Irwin was one of the 19 astronauts selected by NASA in April 1966. He was crew commander of lunar module (LTA-8)-this vehicle finished the first series of thermal vacuum tests on June 1, 1968. He also served as a member of the astronaut support crew for Apollo 10 and as backup lunar module pilot for the Apollo 12 flight. Irwin served as lunar module pilot for Apollo, July 26 to August 7, 1971. His companions on the flight were David R. Scott, spacecraft commander and Alfred M. Worden, command module pilot. Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, \"Falcon\", remained on the lunar surface for 66 hours, 54 minutes-setting a new record for lunar surface stay time-and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using \"Rover-l\" to transport themselves and their equipment along portions of Hadley Rille and the Apinnine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected approximately 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised in color using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements included: largest payloads ever placed in earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device, mounted on Rover 1; first subsatellite launched in lunar orbit; and first extravehicular activity (EVA) from a command module during transearth coast. The latter feat was accomplished by Worden during three excursions to \"Endeavour's\" SIM bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific splashdown and subsequent recovery by the USS OKINAWA.\n"},{"id":"john_young","name":"john young","body":"In September 1962, Young was selected as an astronaut. He is the first person to fly in space six times from earth, and seven times counting his lunar liftoff. The first flight was with Gus Grissom in Gemini 3, the first manned Gemini mission, on March 23, 1965. This was a complete end-to-end test of the Gemini spacecraft, during which Gus accomplished the first manual change of orbit altitude and plane and the first lifting reentry, and Young operated the first computer on a manned spacecraft. On Gemini 10, July 18-21, 1966, Young, as Commander, and Mike Collins, as Pilot, completed a dual rendezvous with two separate Agena target vehicles. While Young flew close formation on the second Agena, Mike Collins did an extravehicular transfer to retrieve a micro meteorite detector from that Agena. On his third flight, May 18-26, 1969, Young was Command Module Pilot of Apollo 10. Tom Stafford and Gene Cernan were also on this mission which orbited the Moon, completed a lunar rendezvous, and tracked proposed lunar landing sites. His fourth space flight, Apollo 16, April 16-27, 1972, was a lunar exploration mission, with Young as Spacecraft Commander, and Ken Mattingly and Charlie Duke. Young and Duke set up scientific equipment and explored the lunar highlands at Descartes. They collected 200 pounds of rocks and drove over 16 miles in the lunar rover on three separate geology traverses. Young’s fifth flight was as Spacecraft Commander of STS-1, the first flight of the Space Shuttle, April 12-14, 1981, with Bob Crippen as Pilot. The 54-1/2 hour, 36-orbit mission verified Space Shuttle systems performance during launch, on orbit, and entry. Tests of the Orbiter Columbia included evaluation of mechanical systems including the payload bay doors, the attitude and maneuvering rocket thrusters, guidance and navigation systems, and Orbiter/crew compatibility. One hundred and thirty three of the mission’s flight test objectives were accomplished. The Orbiter Columbia was the first manned spaceship tested during ascent, on orbit, and entry without benefit of previous unmanned missions. Columbia was also the first winged reentry vehicle to return from space to a runway landing. It weighed about 98 tons as Young landed it on the dry lakebed at Edwards Air Force Base, California. Young’s sixth flight was as Spacecraft Commander of STS-9, the first Spacelab mission, November 28-December 8, 1983, with Pilot Brewster Shaw, Mission Specialists Bob Parker and Owen Garriott, and Payload Specialists Byron Lichtenberg of the USA and Ulf Merbold of West Germany. The mission successfully completed all 94 of its flight test objectives. For ten days the 6-man crew worked 12-hour shifts around-the-clock, performing more than 70 experiments in the fields of atmospheric physics, Earth observations, space plasma physics, astronomy and solar physics, materials processing and life sciences. The mission returned more scientific and technical data than all the previous Apollo and Skylab missions put together. The Spacelab was brought back for re-use, so that Columbia weighed over 110 tons as Young landed the spaceship at Edwards Air Force Base, California.\n"},{"id":"neil_armstrong","name":"neil armstrong","body":"As a research pilot at NASA’s Flight Research Center, Edwards, California, Armstrong was a project pilot on many pioneering high speed aircraft, including the well known, 4000-mph X-15. He flew more than 200 different models of aircraft, including jets, rockets, helicopters and gliders. Armstrong transferred to astronaut status in 1962. He was assigned as command pilot for the Gemini 8 mission. Gemini 8 was launched on March 16, 1966, and Armstrong performed the first successful docking of two vehicles in space. As spacecraft commander for Apollo 11, the first manned lunar landing mission, Armstrong gained the distinction of being the first man to land a craft on the moon and first to step on its surface. Armstrong subsequently held the position of Deputy Associate Administrator for Aeronautics, NASA Headquarters, Washington, D.C. In this position, he was responsible for the coordination and management of overall NASA research and technology work related to aeronautics.\n"},{"id":"pete_conrad","name":"pete conrad","body":"In September of 1962, Mr. Conrad was selected as an astronaut by NASA. His first flight was Gemini V, which established the space endurance record and placed the United States in the lead for man-hours in space. As commander of Gemini XI, Mr. Conrad helped to set a world's altitude record. He then served as commander of Apollo XII, the second lunar landing. On Mr. Conrad's final mission, he served as commander of Skylab II, the first United States Space Station. In December 1973, after serving 20 years (11 of which were as an astronaut in the space program), Mr. Conrad retired from the U.S. Navy to accept a position as Vice President - Operations and Chief Operating Office of American Television and Communications Corporation (ATC). At ATC, he was responsible for both the operation of existing systems and the national development of new cable television systems. In 1976, he resigned from ATC to accept the position of Vice President and consultant to McDonnell Douglas Corporation. In 1978, he became Vice President of marketing and was responsible for all commercial and military sales for Douglas Aircraft Company. Mr. Conrad then became Senior Vice President-Marketing in 1980. He was appointed as Senior Vice President Marketing and Product Support in 1982 and 1984, was named Staff Vice President of International Business Development for McDonnell Douglas Corporation.\n"}] -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 |
    15 | 16 |
  1. 17 |
    18 |
    19 |

    alan bean

    20 |
    21 | 22 |
    23 |

    Alan Bean was one of the third group of astronauts named by NASA in October 1963. He served as backup astronaut for the Gemini 10 and Apollo 9 missions. Captain Bean was lunar module pilot on Apollo 12, mans second lunar landing. In November 1969, Captain Bean and Captain Pete Conrad landed in the moons Ocean of Stormsafter a flight of some 250,000 miles. They explored the lunar surface, deployed several lunar surface experiments, and installed the first nuclear power generator station on the moon to provide the power source. Captain Richard Gordon remained in lunar orbit photographing landing sites for future missions. Captain Bean was spacecraft commander of Skylab Mission II (SL-3), July 29 to September 25, 1973. With him on the 59-day, 24,400,000 mile world record setting flight were scientist-astronaut Dr. Owen K. Garriott and Marine Corps Lieutenant Colonel Jack R. Lousma. Mission II accomplished 150% of its pre-mission forecast goals. On his next assignment, Captain Bean was backup spacecraft commander of the United States flight crew for the joint American-Russian Apollo-Soyuz Test Project. Captain Bean has logged 1,671 hours and 45 minutes in spaceof which 10 hours and 26 minutes were spent in EVAs on the moon and in earth orbit. 24 |

    25 |
    26 |
    27 |
  2. 28 | 29 |
  3. 30 |
    31 |
    32 |

    alan shepard

    33 |
    34 | 35 |
    36 |

    Rear Admiral Shepard was one of the Mercury astronauts named by NASA in April 1959, and he holds the distinction of being the first American to journey into space. On May 5, 1961, in the Freedom 7 spacecraft, he was launched by a Redstone vehicle on a ballistic trajectory suborbital flight--a flight which carried him to an altitude of 116 statute miles and to a landing point 302 statute miles down the Atlantic Missile Range. In 1963, he was designated Chief of the Astronaut Office with responsibility for monitoring the coordination, scheduling, and control of all activities involving NASA astronauts. This included monitoring the development and implementation of effective training programs to assure the flight readiness of available pilot/non-pilot personnel for assignment to crew positions on manned space flights; furnishing pilot evaluations applicable to the design, construction, and operations of spacecraft systems and related equipment; and providing qualitative scientific and engineering observations to facilitate overall mission planning, formulation of feasible operational procedures, and selection and conduct of specific experiments for each flight. He was restored to full flight status in May 1969, following corrective surgery for an inner ear disorder. Shepard made his second space flight as spacecraft commander on Apollo 14, January 31 - February 9, 1971. He was accompanied on man's third lunar landing mission by Stuart A. Roosa, command module pilot, and Edgar D. Mitchell, lunar module pilot. Maneuvering their lunar module, "Antares," to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of colored TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations. 37 |

    38 |
    39 |
    40 |
  4. 41 | 42 |
  5. 43 |
    44 |
    45 |

    buzz aldrin

    46 |
    47 | 48 |
    49 |

    Aldrin was one of the third group of astronauts named by NASA in October 1963. On November 11, 1966, he and command pilot James Lovell were launched into space in the Gemini 12 spacecraft on a 4-day flight, which brought the Gemini program to a successful close. Aldrin established a new record for extravehicular activity (EVA), spending 5-1/2 hours outside the spacecraft. He served as lunar module pilot for Apollo 11, July 16-24, 1969, the first manned lunar landing mission. Aldrin followed Neil Armstrong onto the lunar surface on July 20, 1969, completing a 2-hour and 15 minute lunar EVA. In July 1971, Aldrin resigned from NASA. Aldrin has logged 289 hours and 53 minutes in space, of which, 7 hours and 52 minutes were spent in EVA. 50 |

    51 |
    52 |
    53 |
  6. 54 | 55 |
  7. 56 |
    57 |
    58 |

    charles duke

    59 |
    60 | 61 |
    62 |

    Duke was one of the 19 astronauts selected by NASA in April 1966. He served as member of the astronaut support crew for the Apollo 10 flight. He was CAPCOM for Apollo 11, the first landing on the Moon and he served as backup lunar module pilot on Apollo 13. Duke served as lunar module pilot of Apollo 16, April 16-27, 1972. He was accompanied on the fifth manned lunar landing mission by John W. Young (spacecraft commander) and Thomas K. Mattingly II (command module pilot). Apollo 16 was the first scientific expedition to inspect, survey, and sample materials and surface features in the Descartes region of the rugged lunar highlands. Duke and Young commenced their record setting lunar surface stay of 71 hours and 14 minutes by maneuvering the lunar module "Orion" to a landing on the rough Cayley Plains. In three subsequent excursions onto the lunar surface, they each logged 20 hours and 15 minutes in extravehicular activities involving the emplacement and activation of scientific equipment and experiments, the collection of nearly 213 pounds of rock and soil samples, and the evaluation and use of Rover-2 over the roughest and blockiest surface yet encountered on the moon. Other Apollo 16 achievements included the largest payload placed in lunar orbit (76, 109 pounds); first cosmic ray detector deployed on lunar surface; first lunar observatory with the far UV camera; and longest in-flight EVA from a command module during transearth coast (1 hour and 13 minutes). The latter feat was accomplished by Mattingly when he ventured out to "Casper's" SIM-bay for the retrieval of vital film cassettes from the panoramic and mapping cameras. Apollo 16 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS TICONDEROGA. With the completion of his first space flight, Duke has logged 265 hours in space and over 21 hours of extra vehicular activity. Duke also served as backup lunar module pilot for Apollo 17. 63 |

    64 |
    65 |
    66 |
  8. 67 | 68 |
  9. 69 |
    70 |
    71 |

    david scott

    72 |
    73 | 74 |
    75 |

    Scott was one of the third group of astronauts named by NASA in October 1963. On March 16, 1966, he and command pilot Neil Armstrong were launched into space on the Gemini 8 mission--a flight originally scheduled to last three days but terminated early due to a malfunctioning thruster. The crew performed the first successful docking of two vehicles in space and demonstrated great piloting skill in overcoming the thruster problem and bringing the spacecraft to a safe landing. Scott served as command module pilot for Apollo 9, March 3-13, 1969. This was the third manned flight in the Apollo series, the second to be launched by a Saturn V, and the first to complete a comprehensive earth-orbital qualification and verification test of a "fully configured Apollo spacecraft." The ten-day flight provided vital information previously not available on the operational performance, stability, and reliability of lunar module propulsion and life support systems. Highlight of this evaluation was completion of a critical lunar-orbit rendezvous simulation and subsequent docking, initiated by James McDivitt and Russell Schweickart from within the lunar module at a separation distance which exceeded 100 miles from the command/service module piloted by Scott. The crew also demonstrated and confirmed the operational feasibility of crew transfer and extravehicular activity techniques and equipment, with Schweickart completing a 46-minute EVA outside the lunar module. During this period, Dave Scott completed a 1-hour stand-up EVA in the open command module hatch photographing Schweickart's activities and also retrieving thermal samples from the command module exterior. Apollo 9 splashed down less than four miles from the helicopter carrier USS GUADALCANAL. In his next assignment, Scott was designated backup spacecraft commander for Apollo 12. He made his third space flight as spacecraft commander of Apollo 15, July 26 - August 7, 1971. His companions on the flight were Alfred M. Worden (command module pilot) and James B. Irwin (lunar module pilot). Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, "Falcon," remained on the lunar surface for 66 hours and 54 minutes (setting a new record for lunar surface stay time) and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using "Rover-1" to transport themselves and their equipment along portions of Hadley Rille and the Apennine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements include: largest payloads ever placed into earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device (mounted on Rover-1); first subsatellite launched in lunar orbit; and first extravehicular (EVA) from a command module during transearth coast. The latter feat performed by Worden during three excursions to "Endeavour's" SIM-bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS OKINAWA. 76 |

    77 |
    78 |
    79 |
  10. 80 | 81 |
  11. 82 |
    83 |
    84 |

    edgar mitchell

    85 |
    86 | 87 |
    88 |

    Mitchell was a member of Group 5, selected for astronaut training in April 1966. He served as a member of the astronaut support crew for Apollo 9 and as backup lunar module pilot for Apollo 10. On January 31, 1971, serving as lunar module pilot, Dr. Edgar Mitchell, then a U.S. Navy Captain, embarked on a journey through outer space of some 500,000 miles that resulted in becoming the sixth man to walk on the moon. That historic journey terminated safely nine days later on February 9, 1971 and was made in the company of two other men of valor Admiral Alan Shepard and Colonel Stuart Roosa. Maneuvering their lunar module, Antares, to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to Earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of color TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations. In completing his first space flight, Mitchell logged a total of 216 hours and 42 minutes in space. He was subsequently designated to serve as backup lunar module pilot for Apollo 16. 89 |

    90 |
    91 |
    92 |
  12. 93 | 94 |
  13. 95 |
    96 |
    97 |

    eugene cernan

    98 |
    99 | 100 |
    101 |

    Captain Cernan was one of fourteen astronauts selected by NASA in October 1963. He occupied the pilot seat alongside of command pilot Tom Stafford on the Gemini IX mission. During this 3-day flight which Began on June 3, 1966, the spacecraft achieved a circular orbit of 161 statute miles; the crew used three different techniques to effect rendezvous with the previously launched Augmented Target Docking Adapter; and Cernan, the second American to walk in space, logged two hours and ten minutes outside the spacecraft in extravehicular activities. The flight ended after 72 hours and 20 minutes with a perfect re-entry and recovery as Gemini IX landed within 1-1/2 miles of the prime recovery ship USS WASP and 3/8 of a mile from the predetermined target. Cernan subsequently served as backup pilot for Gemini 12 and as backup lunar module pilot for Apollo 7. On his second space flight, he was lunar module pilot of Apollo 10, May 18-26, 1969, the first comprehensive lunar-orbital qualification and verification flight test of an Apollo lunar module. He was accompanied on the 248,000 nautical sojourn to the moon by Thomas P. Stafford (spacecraft commander) and John W. Young (commander module pilot). In accomplishing all of the assigned objectives of this mission, Apollo 10 confirmed the operations performance, stability, and reliability of the command/service module and lunar module configuration during trans-lunar coast, lunar orbit insertion, and lunar module separation and descent to within 8 nautical miles of the lunar surface. The latter maneuver involved employing all but the final minutes of the technique prescribed for use in an actual lunar landing, and allowed critical evaluations of the lunar module propulsions systems and rendezvous of the landing radar devices in subsequent rendezvous and re-docking maneuvers. In addition to demonstrating that man could navigate safely and accurately in the moon's gravitational fields, Apollo 10 photographed and mapped tentative landing sites for future missions. Cernan's next assignment was backup spacecraft commander for Apollo 14. He made his third space flight as spacecraft commander of Apollo 17--the last scheduled manned mission to the moon for the United States--which commenced at 11:33 P.M. (CST), December 6, 1972, with the first manned nighttime launch, and concluded on December 19, 1972. With him on the voyage of the command module "America" and the lunar module "Challenger" were Ronald Evans (command module pilot) and Harrison H. (Jack) Schmitt (lunar module pilot). In maneuvering "Challenger" to a landing at Taurus-Littrow, located on the southeast edge of Mare Serenitatis, Cernan and Schmitt activated a base of operations from which they completed three highly successful excursions to the nearby craters and the Taurus mountains, making the Moon their home for over three days. This last mission to the moon established several new records for manned space flight that include: longest manned lunar landing flight (301 hours 51 minutes); longest lunar surface extravehicular activities (22 hours 6 minutes); largest lunar sample return (an estimated 115 kg (249 lbs.); and longest time in lunar orbit (147 hours 48 minutes). While Cernan and Schmitt conducted activities on the lunar surface, Evans remained in lunar orbit aboard the "America" completing assigned work tasks requiring geological observations, handheld photography of specific targets, and the control of cameras and other highly sophisticated scientific equipment carried in the command module SIM-bay. Evans also completed a 1-hour, 6-minute extravehicular activity on the transearth coast phase of the return flight, successfully retrieving three camera cassettes and completing a personal inspection of the equipment bay area. Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 miles from the target point and 4.3 miles form the prime recovery ship USS TICONDEROGA. Captain Cernan was the second American to have walked in space having spanned the circumference of the world twice in a little more than 2-1/2 hours. He was one of the two men to have flown to the moon on two occasions, and as commander of the last mission to the moon, Apollo 17, had the privilege and distinction of being the last man to have left his footprints on the surface of the moon. 102 |

    103 |
    104 |
    105 |
  14. 106 | 107 |
  15. 108 |
    109 |
    110 |

    harrison schmitt

    111 |
    112 | 113 |
    114 |

    Dr. Schmitt was selected as a scientist-astronaut by NASA in June 1965. He later completed a 53-week course in flight training at Williams Air Force Base, Arizona. In addition to training for future manned space flights. He was instrumental in providing Apollo flight crews with detailed instruction in lunar navigation, geology, and feature recognition. Schmitt also assisted in the integration of scientific activities into the Apollo lunar missions and participated in research activities requiring geologic, petrographic, and stratigraphic analyses of samples returned from the moon by Apollo missions. On his first journey into space, Dr. Schmitt occupied the lunar module pilot seat for Apollo 17 -- the last scheduled manned Apollo mission to the United States --which commenced at 11:33 p.m. (CST), December 6, 1972, and concluded on December 19, 1972. He was accompanied on the voyage of the command module "America" and the lunar module "Challenger" by Eugene Cernan (spacecraft commander) and Ronald Evans (command module pilot). In maneuvering "Challenger" to a landing at Taurus-Littrow, which is located on the southeast edge of Mare Serenitatis, Schmitt and Cernan activated a base of operations facilitating their completion of three days of exploration. This last Apollo mission to the moon for the United States broke several records set by previous flights and include: longest manned lunar landing flight (301 hours, 51 minutes); longest lunar surface extravehicular activities (22 hours, 4 minutes); largest lunar sample return (an estimated 115 Kg, 249 lbs); and longest time in lunar orbit (147 hours, 48 minutes). Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 mile from the target point and 4.3 miles from the prime recovery ship, USS TICONDEROGA. 115 |

    116 |
    117 |
    118 |
  16. 119 | 120 |
  17. 121 |
    122 |
    123 |

    james irwin

    124 |
    125 | 126 |
    127 |

    Colonel Irwin was one of the 19 astronauts selected by NASA in April 1966. He was crew commander of lunar module (LTA-8)-this vehicle finished the first series of thermal vacuum tests on June 1, 1968. He also served as a member of the astronaut support crew for Apollo 10 and as backup lunar module pilot for the Apollo 12 flight. Irwin served as lunar module pilot for Apollo, July 26 to August 7, 1971. His companions on the flight were David R. Scott, spacecraft commander and Alfred M. Worden, command module pilot. Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, "Falcon", remained on the lunar surface for 66 hours, 54 minutes-setting a new record for lunar surface stay time-and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using "Rover-l" to transport themselves and their equipment along portions of Hadley Rille and the Apinnine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected approximately 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised in color using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements included: largest payloads ever placed in earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device, mounted on Rover 1; first subsatellite launched in lunar orbit; and first extravehicular activity (EVA) from a command module during transearth coast. The latter feat was accomplished by Worden during three excursions to "Endeavour's" SIM bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific splashdown and subsequent recovery by the USS OKINAWA. 128 |

    129 |
    130 |
    131 |
  18. 132 | 133 |
  19. 134 |
    135 |
    136 |

    john young

    137 |
    138 | 139 |
    140 |

    In September 1962, Young was selected as an astronaut. He is the first person to fly in space six times from earth, and seven times counting his lunar liftoff. The first flight was with Gus Grissom in Gemini 3, the first manned Gemini mission, on March 23, 1965. This was a complete end-to-end test of the Gemini spacecraft, during which Gus accomplished the first manual change of orbit altitude and plane and the first lifting reentry, and Young operated the first computer on a manned spacecraft. On Gemini 10, July 18-21, 1966, Young, as Commander, and Mike Collins, as Pilot, completed a dual rendezvous with two separate Agena target vehicles. While Young flew close formation on the second Agena, Mike Collins did an extravehicular transfer to retrieve a micro meteorite detector from that Agena. On his third flight, May 18-26, 1969, Young was Command Module Pilot of Apollo 10. Tom Stafford and Gene Cernan were also on this mission which orbited the Moon, completed a lunar rendezvous, and tracked proposed lunar landing sites. His fourth space flight, Apollo 16, April 16-27, 1972, was a lunar exploration mission, with Young as Spacecraft Commander, and Ken Mattingly and Charlie Duke. Young and Duke set up scientific equipment and explored the lunar highlands at Descartes. They collected 200 pounds of rocks and drove over 16 miles in the lunar rover on three separate geology traverses. Young’s fifth flight was as Spacecraft Commander of STS-1, the first flight of the Space Shuttle, April 12-14, 1981, with Bob Crippen as Pilot. The 54-1/2 hour, 36-orbit mission verified Space Shuttle systems performance during launch, on orbit, and entry. Tests of the Orbiter Columbia included evaluation of mechanical systems including the payload bay doors, the attitude and maneuvering rocket thrusters, guidance and navigation systems, and Orbiter/crew compatibility. One hundred and thirty three of the mission’s flight test objectives were accomplished. The Orbiter Columbia was the first manned spaceship tested during ascent, on orbit, and entry without benefit of previous unmanned missions. Columbia was also the first winged reentry vehicle to return from space to a runway landing. It weighed about 98 tons as Young landed it on the dry lakebed at Edwards Air Force Base, California. Young’s sixth flight was as Spacecraft Commander of STS-9, the first Spacelab mission, November 28-December 8, 1983, with Pilot Brewster Shaw, Mission Specialists Bob Parker and Owen Garriott, and Payload Specialists Byron Lichtenberg of the USA and Ulf Merbold of West Germany. The mission successfully completed all 94 of its flight test objectives. For ten days the 6-man crew worked 12-hour shifts around-the-clock, performing more than 70 experiments in the fields of atmospheric physics, Earth observations, space plasma physics, astronomy and solar physics, materials processing and life sciences. The mission returned more scientific and technical data than all the previous Apollo and Skylab missions put together. The Spacelab was brought back for re-use, so that Columbia weighed over 110 tons as Young landed the spaceship at Edwards Air Force Base, California. 141 |

    142 |
    143 |
    144 |
  20. 145 | 146 |
  21. 147 |
    148 |
    149 |

    neil armstrong

    150 |
    151 | 152 |
    153 |

    As a research pilot at NASA’s Flight Research Center, Edwards, California, Armstrong was a project pilot on many pioneering high speed aircraft, including the well known, 4000-mph X-15. He flew more than 200 different models of aircraft, including jets, rockets, helicopters and gliders. Armstrong transferred to astronaut status in 1962. He was assigned as command pilot for the Gemini 8 mission. Gemini 8 was launched on March 16, 1966, and Armstrong performed the first successful docking of two vehicles in space. As spacecraft commander for Apollo 11, the first manned lunar landing mission, Armstrong gained the distinction of being the first man to land a craft on the moon and first to step on its surface. Armstrong subsequently held the position of Deputy Associate Administrator for Aeronautics, NASA Headquarters, Washington, D.C. In this position, he was responsible for the coordination and management of overall NASA research and technology work related to aeronautics. 154 |

    155 |
    156 |
    157 |
  22. 158 | 159 |
  23. 160 |
    161 |
    162 |

    pete conrad

    163 |
    164 | 165 |
    166 |

    In September of 1962, Mr. Conrad was selected as an astronaut by NASA. His first flight was Gemini V, which established the space endurance record and placed the United States in the lead for man-hours in space. As commander of Gemini XI, Mr. Conrad helped to set a world's altitude record. He then served as commander of Apollo XII, the second lunar landing. On Mr. Conrad's final mission, he served as commander of Skylab II, the first United States Space Station. In December 1973, after serving 20 years (11 of which were as an astronaut in the space program), Mr. Conrad retired from the U.S. Navy to accept a position as Vice President - Operations and Chief Operating Office of American Television and Communications Corporation (ATC). At ATC, he was responsible for both the operation of existing systems and the national development of new cable television systems. In 1976, he resigned from ATC to accept the position of Vice President and consultant to McDonnell Douglas Corporation. In 1978, he became Vice President of marketing and was responsible for all commercial and military sales for Douglas Aircraft Company. Mr. Conrad then became Senior Vice President-Marketing in 1980. He was appointed as Senior Vice President Marketing and Product Support in 1982 and 1984, was named Staff Vice President of International Business Development for McDonnell Douglas Corporation. 167 |

    168 |
    169 |
    170 |
  24. 171 | 172 |
173 |
174 | 175 | 176 | -------------------------------------------------------------------------------- /lunr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.0.0-alpha.1+1474820138 3 | * Copyright (C) 2016 Oliver Nightingale 4 | * MIT Licensed 5 | * @license 6 | */ 7 | 8 | ;(function(){ 9 | 10 | /** 11 | * A convenience function for configuring and constructing 12 | * a new lunr Index. 13 | * 14 | * A lunr.Builder instance is created and the pipeline setup 15 | * with a trimmer, stop word filter and stemmer. 16 | * 17 | * This builder object is yielded to the configuration function 18 | * that is passed as a parameter, allowing the list of fields 19 | * and other builder parameters to be customised. 20 | * 21 | * All documents _must_ be added within the passed config function. 22 | * 23 | * @example 24 | * var idx = lunr(function () { 25 | * this.field('title') 26 | * this.field('body') 27 | * this.ref('id') 28 | * 29 | * documents.forEach(function (doc) { 30 | * this.add(doc) 31 | * }, this) 32 | * }) 33 | * 34 | * @see {@link lunr.Builder} 35 | * @see {@link lunr.Pipeline} 36 | * @see {@link lunr.trimmer} 37 | * @see {@link lunr.stopWordFilter} 38 | * @see {@link lunr.stemmer} 39 | * @namespace {function} lunr 40 | */ 41 | var lunr = function (config) { 42 | var builder = new lunr.Builder 43 | 44 | builder.pipeline.add( 45 | lunr.trimmer, 46 | lunr.stopWordFilter, 47 | lunr.stemmer 48 | ) 49 | 50 | builder.searchPipeline.add( 51 | lunr.stemmer 52 | ) 53 | 54 | config.call(builder) 55 | return builder.build() 56 | } 57 | /*! 58 | * lunr.utils 59 | * Copyright (C) 2016 Oliver Nightingale 60 | */ 61 | 62 | /** 63 | * A namespace containing utils for the rest of the lunr library 64 | */ 65 | lunr.utils = {} 66 | 67 | /** 68 | * Print a warning message to the console. 69 | * 70 | * @param {String} message The message to be printed. 71 | * @memberOf Utils 72 | */ 73 | lunr.utils.warn = (function (global) { 74 | /* eslint-disable no-console */ 75 | return function (message) { 76 | if (global.console && console.warn) { 77 | console.warn(message) 78 | } 79 | } 80 | /* eslint-enable no-console */ 81 | })(this) 82 | 83 | /** 84 | * Convert an object to a string. 85 | * 86 | * In the case of `null` and `undefined` the function returns 87 | * the empty string, in all other cases the result of calling 88 | * `toString` on the passed object is returned. 89 | * 90 | * @param {Any} obj The object to convert to a string. 91 | * @return {String} string representation of the passed object. 92 | * @memberOf Utils 93 | */ 94 | lunr.utils.asString = function (obj) { 95 | if (obj === void 0 || obj === null) { 96 | return "" 97 | } else { 98 | return obj.toString() 99 | } 100 | } 101 | /** 102 | * A function to calculate the inverse document frequency for 103 | * a posting. This is shared between the builder and the index 104 | * 105 | * @private 106 | * @param {object} posting - The posting for a given term 107 | * @param {number} documentCount - The total number of documents. 108 | */ 109 | lunr.idf = function (posting, documentCount) { 110 | var documentsWithTerm = 0 111 | 112 | for (var fieldName in posting) { 113 | if (fieldName == '_index') continue // Ignore the term index, its not a field 114 | documentsWithTerm += Object.keys(posting[fieldName]).length 115 | } 116 | 117 | return (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5) 118 | } 119 | 120 | /** 121 | * A token wraps a string representation of a token 122 | * as it is passed through the text processing pipeline. 123 | * 124 | * @constructor 125 | * @param {string} [str=''] - The string token being wrapped. 126 | * @param {object} [metadata={}] - Metadata associated with this token. 127 | */ 128 | lunr.Token = function (str, metadata) { 129 | this.str = str || "" 130 | this.metadata = metadata || {} 131 | } 132 | 133 | /** 134 | * Returns the token string that is being wrapped by this object. 135 | * 136 | * @returns {string} 137 | */ 138 | lunr.Token.prototype.toString = function () { 139 | return this.str 140 | } 141 | 142 | /** 143 | * A token update function is used when updating or optionally 144 | * when cloning a token. 145 | * 146 | * @callback lunr.Token~updateFunction 147 | * @param {string} str - The string representation of the token. 148 | * @param {Object} metadata - All metadata associated with this token. 149 | */ 150 | 151 | /** 152 | * Applies the given function to the wrapped string token. 153 | * 154 | * @example 155 | * token.update(function (str, metadata) { 156 | * return str.toUpperCase() 157 | * }) 158 | * 159 | * @param {lunr.Token~updateFunction} fn - A function to apply to the token string. 160 | * @returns {lunr.Token} 161 | */ 162 | lunr.Token.prototype.update = function (fn) { 163 | this.str = fn(this.str, this.metadata) 164 | return this 165 | } 166 | 167 | /** 168 | * Creates a clone of this token. Optionally a function can be 169 | * applied to the cloned token. 170 | * 171 | * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token. 172 | * @returns {lunr.Token} 173 | */ 174 | lunr.Token.prototype.clone = function (fn) { 175 | fn = fn || function (s) { return s } 176 | return new lunr.Token (fn(this.str, this.metadata), this.metadata) 177 | } 178 | /*! 179 | * lunr.tokenizer 180 | * Copyright (C) 2016 Oliver Nightingale 181 | */ 182 | 183 | /** 184 | * A function for splitting a string into tokens ready to be inserted into 185 | * the search index. Uses `lunr.tokenizer.separator` to split strings, change 186 | * the value of this property to change how strings are split into tokens. 187 | * 188 | * This tokenizer will convert its parameter to a string by calling `toString` and 189 | * then will split this string on the character in `lunr.tokenizer.separator`. 190 | * Arrays will have their elements converted to strings and wrapped in a lunr.Token. 191 | * 192 | * @static 193 | * @param {?(string|object|object[])} obj - The object to convert into tokens 194 | * @returns {lunr.Token[]} 195 | */ 196 | lunr.tokenizer = function (obj) { 197 | if (obj == null || obj == undefined) { 198 | return [] 199 | } 200 | 201 | if (Array.isArray(obj)) { 202 | return obj.map(function (t) { 203 | return new lunr.Token(lunr.utils.asString(t).toLowerCase()) 204 | }) 205 | } 206 | 207 | var str = obj.toString().trim().toLowerCase(), 208 | len = str.length, 209 | tokens = [] 210 | 211 | for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) { 212 | var char = str.charAt(sliceEnd), 213 | sliceLength = sliceEnd - sliceStart 214 | 215 | if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) { 216 | 217 | if (sliceLength > 0) { 218 | tokens.push( 219 | new lunr.Token (str.slice(sliceStart, sliceEnd), { 220 | position: [sliceStart, sliceLength], 221 | index: tokens.length 222 | }) 223 | ) 224 | } 225 | 226 | sliceStart = sliceEnd + 1 227 | } 228 | 229 | } 230 | 231 | return tokens 232 | } 233 | 234 | /** 235 | * The separator used to split a string into tokens. Override this property to change the behaviour of 236 | * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens. 237 | * 238 | * @static 239 | * @see lunr.tokenizer 240 | */ 241 | lunr.tokenizer.separator = /[\s\-]+/ 242 | /*! 243 | * lunr.Pipeline 244 | * Copyright (C) 2016 Oliver Nightingale 245 | */ 246 | 247 | /** 248 | * lunr.Pipelines maintain an ordered list of functions to be applied to all 249 | * tokens in documents entering the search index and queries being ran against 250 | * the index. 251 | * 252 | * An instance of lunr.Index created with the lunr shortcut will contain a 253 | * pipeline with a stop word filter and an English language stemmer. Extra 254 | * functions can be added before or after either of these functions or these 255 | * default functions can be removed. 256 | * 257 | * When run the pipeline will call each function in turn, passing a token, the 258 | * index of that token in the original list of all tokens and finally a list of 259 | * all the original tokens. 260 | * 261 | * The output of functions in the pipeline will be passed to the next function 262 | * in the pipeline. To exclude a token from entering the index the function 263 | * should return undefined, the rest of the pipeline will not be called with 264 | * this token. 265 | * 266 | * For serialisation of pipelines to work, all functions used in an instance of 267 | * a pipeline should be registered with lunr.Pipeline. Registered functions can 268 | * then be loaded. If trying to load a serialised pipeline that uses functions 269 | * that are not registered an error will be thrown. 270 | * 271 | * If not planning on serialising the pipeline then registering pipeline functions 272 | * is not necessary. 273 | * 274 | * @constructor 275 | */ 276 | lunr.Pipeline = function () { 277 | this._stack = [] 278 | } 279 | 280 | lunr.Pipeline.registeredFunctions = {} 281 | 282 | /** 283 | * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token 284 | * string as well as all known metadata. A pipeline function can mutate the token string 285 | * or mutate (or add) metadata for a given token. 286 | * 287 | * A pipeline function can indicate that the passed token should be discarded by returning 288 | * null. This token will not be passed to any downstream pipeline functions and will not be 289 | * added to the index. 290 | * 291 | * Multiple tokens can be returned by returning an array of tokens. Each token will be passed 292 | * to any downstream pipeline functions and all will returned tokens will be added to the index. 293 | * 294 | * Any number of pipeline functions may be chained together using a lunr.Pipeline. 295 | * 296 | * @interface lunr.PipelineFunction 297 | * @param {lunr.Token} token - A token from the document being processed. 298 | * @param {number} i - The index of this token in the complete list of tokens for this document/field. 299 | * @param {lunr.Token[]} tokens - All tokens for this document/field. 300 | * @returns {(?lunr.Token|lunr.Token[])} 301 | */ 302 | 303 | /** 304 | * Register a function with the pipeline. 305 | * 306 | * Functions that are used in the pipeline should be registered if the pipeline 307 | * needs to be serialised, or a serialised pipeline needs to be loaded. 308 | * 309 | * Registering a function does not add it to a pipeline, functions must still be 310 | * added to instances of the pipeline for them to be used when running a pipeline. 311 | * 312 | * @param {lunr.PipelineFunction} fn - The function to check for. 313 | * @param {String} label - The label to register this function with 314 | */ 315 | lunr.Pipeline.registerFunction = function (fn, label) { 316 | if (label in this.registeredFunctions) { 317 | lunr.utils.warn('Overwriting existing registered function: ' + label) 318 | } 319 | 320 | fn.label = label 321 | lunr.Pipeline.registeredFunctions[fn.label] = fn 322 | } 323 | 324 | /** 325 | * Warns if the function is not registered as a Pipeline function. 326 | * 327 | * @param {lunr.PipelineFunction} fn - The function to check for. 328 | * @private 329 | */ 330 | lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { 331 | var isRegistered = fn.label && (fn.label in this.registeredFunctions) 332 | 333 | if (!isRegistered) { 334 | lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) 335 | } 336 | } 337 | 338 | /** 339 | * Loads a previously serialised pipeline. 340 | * 341 | * All functions to be loaded must already be registered with lunr.Pipeline. 342 | * If any function from the serialised data has not been registered then an 343 | * error will be thrown. 344 | * 345 | * @param {Object} serialised - The serialised pipeline to load. 346 | * @returns {lunr.Pipeline} 347 | */ 348 | lunr.Pipeline.load = function (serialised) { 349 | var pipeline = new lunr.Pipeline 350 | 351 | serialised.forEach(function (fnName) { 352 | var fn = lunr.Pipeline.registeredFunctions[fnName] 353 | 354 | if (fn) { 355 | pipeline.add(fn) 356 | } else { 357 | throw new Error('Cannot load unregistered function: ' + fnName) 358 | } 359 | }) 360 | 361 | return pipeline 362 | } 363 | 364 | /** 365 | * Adds new functions to the end of the pipeline. 366 | * 367 | * Logs a warning if the function has not been registered. 368 | * 369 | * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline. 370 | */ 371 | lunr.Pipeline.prototype.add = function () { 372 | var fns = Array.prototype.slice.call(arguments) 373 | 374 | fns.forEach(function (fn) { 375 | lunr.Pipeline.warnIfFunctionNotRegistered(fn) 376 | this._stack.push(fn) 377 | }, this) 378 | } 379 | 380 | /** 381 | * Adds a single function after a function that already exists in the 382 | * pipeline. 383 | * 384 | * Logs a warning if the function has not been registered. 385 | * 386 | * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline. 387 | * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline. 388 | */ 389 | lunr.Pipeline.prototype.after = function (existingFn, newFn) { 390 | lunr.Pipeline.warnIfFunctionNotRegistered(newFn) 391 | 392 | var pos = this._stack.indexOf(existingFn) 393 | if (pos == -1) { 394 | throw new Error('Cannot find existingFn') 395 | } 396 | 397 | pos = pos + 1 398 | this._stack.splice(pos, 0, newFn) 399 | } 400 | 401 | /** 402 | * Adds a single function before a function that already exists in the 403 | * pipeline. 404 | * 405 | * Logs a warning if the function has not been registered. 406 | * 407 | * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline. 408 | * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline. 409 | */ 410 | lunr.Pipeline.prototype.before = function (existingFn, newFn) { 411 | lunr.Pipeline.warnIfFunctionNotRegistered(newFn) 412 | 413 | var pos = this._stack.indexOf(existingFn) 414 | if (pos == -1) { 415 | throw new Error('Cannot find existingFn') 416 | } 417 | 418 | this._stack.splice(pos, 0, newFn) 419 | } 420 | 421 | /** 422 | * Removes a function from the pipeline. 423 | * 424 | * @param {lunr.PipelineFunction} fn The function to remove from the pipeline. 425 | */ 426 | lunr.Pipeline.prototype.remove = function (fn) { 427 | var pos = this._stack.indexOf(fn) 428 | if (pos == -1) { 429 | return 430 | } 431 | 432 | this._stack.splice(pos, 1) 433 | } 434 | 435 | /** 436 | * Runs the current list of functions that make up the pipeline against the 437 | * passed tokens. 438 | * 439 | * @param {Array} tokens The tokens to run through the pipeline. 440 | * @returns {Array} 441 | */ 442 | lunr.Pipeline.prototype.run = function (tokens) { 443 | var stackLength = this._stack.length 444 | 445 | for (var i = 0; i < stackLength; i++) { 446 | var fn = this._stack[i] 447 | 448 | tokens = tokens.reduce(function (memo, token, j) { 449 | var result = fn(token, j, tokens) 450 | 451 | if (result === void 0 || result === '') return memo 452 | 453 | return memo.concat(result) 454 | }, []) 455 | } 456 | 457 | return tokens 458 | } 459 | 460 | /** 461 | * Convenience method for passing a string through a pipeline and getting 462 | * strings out. This method takes care of wrapping the passed string in a 463 | * token and mapping the resulting tokens back to strings. 464 | * 465 | * @param {string} str - The string to pass through the pipeline. 466 | * @returns {string[]} 467 | */ 468 | lunr.Pipeline.prototype.runString = function (str) { 469 | var token = new lunr.Token (str) 470 | 471 | return this.run([token]).map(function (t) { 472 | return t.toString() 473 | }) 474 | } 475 | 476 | /** 477 | * Resets the pipeline by removing any existing processors. 478 | * 479 | */ 480 | lunr.Pipeline.prototype.reset = function () { 481 | this._stack = [] 482 | } 483 | 484 | /** 485 | * Returns a representation of the pipeline ready for serialisation. 486 | * 487 | * Logs a warning if the function has not been registered. 488 | * 489 | * @returns {Array} 490 | */ 491 | lunr.Pipeline.prototype.toJSON = function () { 492 | return this._stack.map(function (fn) { 493 | lunr.Pipeline.warnIfFunctionNotRegistered(fn) 494 | 495 | return fn.label 496 | }) 497 | } 498 | /*! 499 | * lunr.Vector 500 | * Copyright (C) 2016 Oliver Nightingale 501 | */ 502 | 503 | /** 504 | * A vector is used to construct the vector space of documents and queries. These 505 | * vectors support operations to determine the similarity between two documents or 506 | * a document and a query. 507 | * 508 | * Normally no parameters are required for initializing a vector, but in the case of 509 | * loading a previously dumped vector the raw elements can be provided to the constructor. 510 | * 511 | * For performance reasons vectors are implemented with a flat array, where an elements 512 | * index is immediately followed by its value. E.g. [index, value, index, value]. This 513 | * allows the underlying array to be as sparse as possible and still offer decent 514 | * performance when being used for vector calculations. 515 | * 516 | * @constructor 517 | * @param {Number[]} [elements] - The flat list of element index and element value pairs. 518 | */ 519 | lunr.Vector = function (elements) { 520 | this._magnitude = 0 521 | this.elements = elements || [] 522 | } 523 | 524 | /** 525 | * Inserts an element at an index within the vector. 526 | * 527 | * @param {Number} insertIdx - The index at which the element should be inserted. 528 | * @param {Number} val - The value to be inserted into the vector. 529 | */ 530 | lunr.Vector.prototype.insert = function (insertIdx, val) { 531 | this._magnitude = 0 532 | 533 | if (this.elements.length == 0) { 534 | this.elements.push(insertIdx, val) 535 | return 536 | } 537 | 538 | var start = 0, 539 | end = this.elements.length, 540 | sliceLength = end - start, 541 | pivot = Math.floor((sliceLength / 2) / 2) * 2, 542 | pivotIdx = this.elements[pivot] 543 | 544 | while (sliceLength > 2) { 545 | if (pivotIdx == insertIdx) { 546 | throw "duplicate index" 547 | } 548 | 549 | if (insertIdx > pivotIdx) { 550 | start = pivot 551 | } 552 | 553 | if (insertIdx < pivotIdx) { 554 | end = pivot 555 | } 556 | 557 | sliceLength = end - start 558 | pivot = start + Math.floor((sliceLength / 2) / 2) * 2 559 | pivotIdx = this.elements[pivot] 560 | } 561 | 562 | if (pivotIdx > insertIdx) { 563 | this.elements.splice(pivot, 0, insertIdx, val) 564 | } 565 | 566 | if (pivotIdx < insertIdx) { 567 | this.elements.splice(pivot + 2, 0, insertIdx, val) 568 | } 569 | } 570 | 571 | /** 572 | * Calculates the magnitude of this vector. 573 | * 574 | * @returns {Number} 575 | */ 576 | lunr.Vector.prototype.magnitude = function () { 577 | if (this._magnitude) return this._magnitude 578 | 579 | var sumOfSquares = 0, 580 | elementsLength = this.elements.length 581 | 582 | for (var i = 1; i < elementsLength; i += 2) { 583 | var val = this.elements[i] 584 | sumOfSquares += val * val 585 | } 586 | 587 | return this._magnitude = Math.sqrt(sumOfSquares) 588 | } 589 | 590 | /** 591 | * Calculates the dot product of this vector and another vector. 592 | * 593 | * @param {lunr.Vector} otherVector - The vector to compute the dot product with. 594 | * @returns {Number} 595 | */ 596 | lunr.Vector.prototype.dot = function (otherVector) { 597 | var dotProduct = 0, 598 | a = this.elements, b = otherVector.elements, 599 | aLen = a.length, bLen = b.length, 600 | aVal = 0, bVal = 0, 601 | i = 0, j = 0 602 | 603 | while (i < aLen && j < bLen) { 604 | aVal = a[i], bVal = b[j] 605 | if (aVal < bVal) { 606 | i += 2 607 | } else if (aVal > bVal) { 608 | j += 2 609 | } else if (aVal == bVal) { 610 | dotProduct += a[i + 1] * b[j + 1] 611 | i += 2 612 | j += 2 613 | } 614 | } 615 | 616 | return dotProduct 617 | } 618 | 619 | /** 620 | * Calculates the cosine similarity between this vector and another 621 | * vector. 622 | * 623 | * @param {lunr.Vector} otherVector - The other vector to calculate the 624 | * similarity with. 625 | * @returns {Number} 626 | */ 627 | lunr.Vector.prototype.similarity = function (otherVector) { 628 | return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude()) 629 | } 630 | 631 | /** 632 | * Converts the vector to an array of the elements within the vector. 633 | * 634 | * @returns {Number[]} 635 | */ 636 | lunr.Vector.prototype.toArray = function () { 637 | var output = new Array (this.elements.length / 2) 638 | 639 | for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) { 640 | output[j] = this.elements[i] 641 | } 642 | 643 | return output 644 | } 645 | 646 | /** 647 | * A JSON serializable representation of the vector. 648 | * 649 | * @returns {Number[]} 650 | */ 651 | lunr.Vector.prototype.toJSON = function () { 652 | return this.elements 653 | } 654 | /* eslint-disable */ 655 | /*! 656 | * lunr.stemmer 657 | * Copyright (C) 2016 Oliver Nightingale 658 | * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt 659 | */ 660 | 661 | /** 662 | * lunr.stemmer is an english language stemmer, this is a JavaScript 663 | * implementation of the PorterStemmer taken from http://tartarus.org/~martin 664 | * 665 | * @static 666 | * @implements {lunr.PipelineFunction} 667 | * @param {lunr.Token} token - The string to stem 668 | * @returns {lunr.Token} 669 | * @see {@link lunr.Pipeline} 670 | */ 671 | lunr.stemmer = (function(){ 672 | var step2list = { 673 | "ational" : "ate", 674 | "tional" : "tion", 675 | "enci" : "ence", 676 | "anci" : "ance", 677 | "izer" : "ize", 678 | "bli" : "ble", 679 | "alli" : "al", 680 | "entli" : "ent", 681 | "eli" : "e", 682 | "ousli" : "ous", 683 | "ization" : "ize", 684 | "ation" : "ate", 685 | "ator" : "ate", 686 | "alism" : "al", 687 | "iveness" : "ive", 688 | "fulness" : "ful", 689 | "ousness" : "ous", 690 | "aliti" : "al", 691 | "iviti" : "ive", 692 | "biliti" : "ble", 693 | "logi" : "log" 694 | }, 695 | 696 | step3list = { 697 | "icate" : "ic", 698 | "ative" : "", 699 | "alize" : "al", 700 | "iciti" : "ic", 701 | "ical" : "ic", 702 | "ful" : "", 703 | "ness" : "" 704 | }, 705 | 706 | c = "[^aeiou]", // consonant 707 | v = "[aeiouy]", // vowel 708 | C = c + "[^aeiouy]*", // consonant sequence 709 | V = v + "[aeiou]*", // vowel sequence 710 | 711 | mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 712 | meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 713 | mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 714 | s_v = "^(" + C + ")?" + v; // vowel in stem 715 | 716 | var re_mgr0 = new RegExp(mgr0); 717 | var re_mgr1 = new RegExp(mgr1); 718 | var re_meq1 = new RegExp(meq1); 719 | var re_s_v = new RegExp(s_v); 720 | 721 | var re_1a = /^(.+?)(ss|i)es$/; 722 | var re2_1a = /^(.+?)([^s])s$/; 723 | var re_1b = /^(.+?)eed$/; 724 | var re2_1b = /^(.+?)(ed|ing)$/; 725 | var re_1b_2 = /.$/; 726 | var re2_1b_2 = /(at|bl|iz)$/; 727 | var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$"); 728 | var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 729 | 730 | var re_1c = /^(.+?[^aeiou])y$/; 731 | var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 732 | 733 | var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 734 | 735 | var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 736 | var re2_4 = /^(.+?)(s|t)(ion)$/; 737 | 738 | var re_5 = /^(.+?)e$/; 739 | var re_5_1 = /ll$/; 740 | var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 741 | 742 | var porterStemmer = function porterStemmer(w) { 743 | var stem, 744 | suffix, 745 | firstch, 746 | re, 747 | re2, 748 | re3, 749 | re4; 750 | 751 | if (w.length < 3) { return w; } 752 | 753 | firstch = w.substr(0,1); 754 | if (firstch == "y") { 755 | w = firstch.toUpperCase() + w.substr(1); 756 | } 757 | 758 | // Step 1a 759 | re = re_1a 760 | re2 = re2_1a; 761 | 762 | if (re.test(w)) { w = w.replace(re,"$1$2"); } 763 | else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } 764 | 765 | // Step 1b 766 | re = re_1b; 767 | re2 = re2_1b; 768 | if (re.test(w)) { 769 | var fp = re.exec(w); 770 | re = re_mgr0; 771 | if (re.test(fp[1])) { 772 | re = re_1b_2; 773 | w = w.replace(re,""); 774 | } 775 | } else if (re2.test(w)) { 776 | var fp = re2.exec(w); 777 | stem = fp[1]; 778 | re2 = re_s_v; 779 | if (re2.test(stem)) { 780 | w = stem; 781 | re2 = re2_1b_2; 782 | re3 = re3_1b_2; 783 | re4 = re4_1b_2; 784 | if (re2.test(w)) { w = w + "e"; } 785 | else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); } 786 | else if (re4.test(w)) { w = w + "e"; } 787 | } 788 | } 789 | 790 | // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say) 791 | re = re_1c; 792 | if (re.test(w)) { 793 | var fp = re.exec(w); 794 | stem = fp[1]; 795 | w = stem + "i"; 796 | } 797 | 798 | // Step 2 799 | re = re_2; 800 | if (re.test(w)) { 801 | var fp = re.exec(w); 802 | stem = fp[1]; 803 | suffix = fp[2]; 804 | re = re_mgr0; 805 | if (re.test(stem)) { 806 | w = stem + step2list[suffix]; 807 | } 808 | } 809 | 810 | // Step 3 811 | re = re_3; 812 | if (re.test(w)) { 813 | var fp = re.exec(w); 814 | stem = fp[1]; 815 | suffix = fp[2]; 816 | re = re_mgr0; 817 | if (re.test(stem)) { 818 | w = stem + step3list[suffix]; 819 | } 820 | } 821 | 822 | // Step 4 823 | re = re_4; 824 | re2 = re2_4; 825 | if (re.test(w)) { 826 | var fp = re.exec(w); 827 | stem = fp[1]; 828 | re = re_mgr1; 829 | if (re.test(stem)) { 830 | w = stem; 831 | } 832 | } else if (re2.test(w)) { 833 | var fp = re2.exec(w); 834 | stem = fp[1] + fp[2]; 835 | re2 = re_mgr1; 836 | if (re2.test(stem)) { 837 | w = stem; 838 | } 839 | } 840 | 841 | // Step 5 842 | re = re_5; 843 | if (re.test(w)) { 844 | var fp = re.exec(w); 845 | stem = fp[1]; 846 | re = re_mgr1; 847 | re2 = re_meq1; 848 | re3 = re3_5; 849 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { 850 | w = stem; 851 | } 852 | } 853 | 854 | re = re_5_1; 855 | re2 = re_mgr1; 856 | if (re.test(w) && re2.test(w)) { 857 | re = re_1b_2; 858 | w = w.replace(re,""); 859 | } 860 | 861 | // and turn initial Y back to y 862 | 863 | if (firstch == "y") { 864 | w = firstch.toLowerCase() + w.substr(1); 865 | } 866 | 867 | return w; 868 | }; 869 | 870 | return function (token) { 871 | return token.update(porterStemmer); 872 | } 873 | })(); 874 | 875 | lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') 876 | /*! 877 | * lunr.stopWordFilter 878 | * Copyright (C) 2016 Oliver Nightingale 879 | */ 880 | 881 | /** 882 | * lunr.generateStopWordFilter builds a stopWordFilter function from the provided 883 | * list of stop words. 884 | * 885 | * The built in lunr.stopWordFilter is built using this generator and can be used 886 | * to generate custom stopWordFilters for applications or non English languages. 887 | * 888 | * @param {Array} token The token to pass through the filter 889 | * @returns {lunr.PipelineFunction} 890 | * @see lunr.Pipeline 891 | * @see lunr.stopWordFilter 892 | */ 893 | lunr.generateStopWordFilter = function (stopWords) { 894 | var words = stopWords.reduce(function (memo, stopWord) { 895 | memo[stopWord] = stopWord 896 | return memo 897 | }, {}) 898 | 899 | return function (token) { 900 | if (token && words[token.toString()] !== token.toString()) return token 901 | } 902 | } 903 | 904 | /** 905 | * lunr.stopWordFilter is an English language stop word list filter, any words 906 | * contained in the list will not be passed through the filter. 907 | * 908 | * This is intended to be used in the Pipeline. If the token does not pass the 909 | * filter then undefined will be returned. 910 | * 911 | * @implements {lunr.PipelineFunction} 912 | * @params {lunr.Token} token - A token to check for being a stop word. 913 | * @returns {lunr.Token} 914 | * @see {@link lunr.Pipeline} 915 | */ 916 | lunr.stopWordFilter = lunr.generateStopWordFilter([ 917 | 'a', 918 | 'able', 919 | 'about', 920 | 'across', 921 | 'after', 922 | 'all', 923 | 'almost', 924 | 'also', 925 | 'am', 926 | 'among', 927 | 'an', 928 | 'and', 929 | 'any', 930 | 'are', 931 | 'as', 932 | 'at', 933 | 'be', 934 | 'because', 935 | 'been', 936 | 'but', 937 | 'by', 938 | 'can', 939 | 'cannot', 940 | 'could', 941 | 'dear', 942 | 'did', 943 | 'do', 944 | 'does', 945 | 'either', 946 | 'else', 947 | 'ever', 948 | 'every', 949 | 'for', 950 | 'from', 951 | 'get', 952 | 'got', 953 | 'had', 954 | 'has', 955 | 'have', 956 | 'he', 957 | 'her', 958 | 'hers', 959 | 'him', 960 | 'his', 961 | 'how', 962 | 'however', 963 | 'i', 964 | 'if', 965 | 'in', 966 | 'into', 967 | 'is', 968 | 'it', 969 | 'its', 970 | 'just', 971 | 'least', 972 | 'let', 973 | 'like', 974 | 'likely', 975 | 'may', 976 | 'me', 977 | 'might', 978 | 'most', 979 | 'must', 980 | 'my', 981 | 'neither', 982 | 'no', 983 | 'nor', 984 | 'not', 985 | 'of', 986 | 'off', 987 | 'often', 988 | 'on', 989 | 'only', 990 | 'or', 991 | 'other', 992 | 'our', 993 | 'own', 994 | 'rather', 995 | 'said', 996 | 'say', 997 | 'says', 998 | 'she', 999 | 'should', 1000 | 'since', 1001 | 'so', 1002 | 'some', 1003 | 'than', 1004 | 'that', 1005 | 'the', 1006 | 'their', 1007 | 'them', 1008 | 'then', 1009 | 'there', 1010 | 'these', 1011 | 'they', 1012 | 'this', 1013 | 'tis', 1014 | 'to', 1015 | 'too', 1016 | 'twas', 1017 | 'us', 1018 | 'wants', 1019 | 'was', 1020 | 'we', 1021 | 'were', 1022 | 'what', 1023 | 'when', 1024 | 'where', 1025 | 'which', 1026 | 'while', 1027 | 'who', 1028 | 'whom', 1029 | 'why', 1030 | 'will', 1031 | 'with', 1032 | 'would', 1033 | 'yet', 1034 | 'you', 1035 | 'your' 1036 | ]) 1037 | 1038 | lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') 1039 | /*! 1040 | * lunr.trimmer 1041 | * Copyright (C) 2016 Oliver Nightingale 1042 | */ 1043 | 1044 | /** 1045 | * lunr.trimmer is a pipeline function for trimming non word 1046 | * characters from the beginning and end of tokens before they 1047 | * enter the index. 1048 | * 1049 | * This implementation may not work correctly for non latin 1050 | * characters and should either be removed or adapted for use 1051 | * with languages with non-latin characters. 1052 | * 1053 | * @static 1054 | * @implements {lunr.PipelineFunction} 1055 | * @param {lunr.Token} token The token to pass through the filter 1056 | * @returns {lunr.Token} 1057 | * @see lunr.Pipeline 1058 | */ 1059 | lunr.trimmer = function (token) { 1060 | return token.update(function (s) { 1061 | return s.replace(/^\W+/, '').replace(/\W+$/, '') 1062 | }) 1063 | } 1064 | 1065 | lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') 1066 | /*! 1067 | * lunr.TokenSet 1068 | * Copyright (C) 2016 Oliver Nightingale 1069 | */ 1070 | 1071 | /** 1072 | * A token set is used to store the unique list of all tokens 1073 | * within an index. Token sets are also used to represent an 1074 | * incoming query to the index, this query token set and index 1075 | * token set are then intersected to find which tokens to look 1076 | * up in the inverted index. 1077 | * 1078 | * A token set can hold multiple tokens, as in the case of the 1079 | * index token set, or it can hold a single token as in the 1080 | * case of a simple query token set. 1081 | * 1082 | * Additionally token sets are used to perform wildcard matching. 1083 | * Leading, contained and trailing wildcards are supported, and 1084 | * from this edit distance matching can also be provided. 1085 | * 1086 | * Token sets are implemented as a minimal finite state automata, 1087 | * where both common prefixes and suffixes are shared between tokens. 1088 | * This helps to reduce the space used for storing the token set. 1089 | * 1090 | * @constructor 1091 | */ 1092 | lunr.TokenSet = function () { 1093 | this.final = false 1094 | this.edges = {} 1095 | } 1096 | 1097 | /** 1098 | * Creates a TokenSet instance from the given sorted array of words. 1099 | * 1100 | * @param {String[]} arr - A sorted array of strings to create the set from. 1101 | * @returns {lunr.TokenSet} 1102 | * @throws Will throw an error if the input array is not sorted. 1103 | */ 1104 | lunr.TokenSet.fromArray = function (arr) { 1105 | var builder = new lunr.TokenSet.Builder 1106 | 1107 | for (var i = 0, len = arr.length; i < len; i++) { 1108 | builder.insert(arr[i]) 1109 | } 1110 | 1111 | builder.finish() 1112 | return builder.root 1113 | } 1114 | 1115 | /** 1116 | * Creates a token set from a query clause. 1117 | * 1118 | * @private 1119 | * @param {Object} clause - A single clause from lunr.Query. 1120 | * @param {string} clause.term - The query clause term. 1121 | * @param {number} [clause.editDistance] - The optional edit distance for the term. 1122 | * @returns {lunr.TokenSet} 1123 | */ 1124 | lunr.TokenSet.fromClause = function (clause) { 1125 | if ('editDistance' in clause) { 1126 | return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance) 1127 | } else { 1128 | return lunr.TokenSet.fromString(clause.term) 1129 | } 1130 | } 1131 | 1132 | /** 1133 | * Creates a token set representing a single string with a specified 1134 | * edit distance. 1135 | * 1136 | * Insertions, deletions, substitutions and transpositions are each 1137 | * treated as an edit distance of 1. 1138 | * 1139 | * Increasing the allowed edit distance will have a dramatic impact 1140 | * on the performance of both creating and intersecting these TokenSets. 1141 | * It is advised to keep the edit distance less than 3. 1142 | * 1143 | * @param {string} str - The string to create the token set from. 1144 | * @param {number} editDistance - The allowed edit distance to match. 1145 | * @returns {lunr.Vector} 1146 | */ 1147 | lunr.TokenSet.fromFuzzyString = function (str, editDistance) { 1148 | var root = new lunr.TokenSet 1149 | 1150 | var stack = [{ 1151 | node: root, 1152 | editsRemaining: editDistance, 1153 | str: str 1154 | }] 1155 | 1156 | while (stack.length) { 1157 | var frame = stack.pop() 1158 | 1159 | // no edit 1160 | if (frame.str.length > 0) { 1161 | var char = frame.str.charAt(0), 1162 | noEditNode 1163 | 1164 | if (char in frame.node.edges) { 1165 | noEditNode = frame.node.edges[char] 1166 | } else { 1167 | noEditNode = new lunr.TokenSet 1168 | frame.node.edges[char] = noEditNode 1169 | } 1170 | 1171 | if (frame.str.length == 1) { 1172 | noEditNode.final = true 1173 | } else { 1174 | stack.push({ 1175 | node: noEditNode, 1176 | editsRemaining: frame.editsRemaining, 1177 | str: frame.str.slice(1) 1178 | }) 1179 | } 1180 | } 1181 | 1182 | // deletion 1183 | // can only do a deletion if we have enough edits remaining 1184 | // and if there are characters left to delete in the string 1185 | if (frame.editsRemaining > 0 && frame.str.length > 1) { 1186 | var char = frame.str.charAt(1), 1187 | deletionNode 1188 | 1189 | if (char in frame.node.edges) { 1190 | deletionNode = frame.node.edges[char] 1191 | } else { 1192 | deletionNode = new lunr.TokenSet 1193 | frame.node.edges[char] = deletionNode 1194 | } 1195 | 1196 | if (frame.str.length <= 2) { 1197 | deletionNode.final = true 1198 | } else { 1199 | stack.push({ 1200 | node: deletionNode, 1201 | editsRemaining: frame.editsRemaining - 1, 1202 | str: frame.str.slice(2) 1203 | }) 1204 | } 1205 | } 1206 | 1207 | // deletion 1208 | // just removing the last character from the str 1209 | if (frame.editsRemaining > 0 && frame.str.length == 1) { 1210 | frame.node.final = true 1211 | } 1212 | 1213 | // substitution 1214 | // can only do a substitution if we have enough edits remaining 1215 | // and if there are characters left to substitute 1216 | if (frame.editsRemaining > 0 && frame.str.length >= 1) { 1217 | if ("*" in frame.node.edges) { 1218 | var substitutionNode = frame.node.edges["*"] 1219 | } else { 1220 | var substitutionNode = new lunr.TokenSet 1221 | frame.node.edges["*"] = substitutionNode 1222 | } 1223 | 1224 | if (frame.str.length == 1) { 1225 | substitutionNode.final = true 1226 | } else { 1227 | stack.push({ 1228 | node: substitutionNode, 1229 | editsRemaining: frame.editsRemaining - 1, 1230 | str: frame.str.slice(1) 1231 | }) 1232 | } 1233 | } 1234 | 1235 | // insertion 1236 | // can only do insertion if there are edits remaining 1237 | if (frame.editsRemaining > 0) { 1238 | if ("*" in frame.node.edges) { 1239 | var insertionNode = frame.node.edges["*"] 1240 | } else { 1241 | var insertionNode = new lunr.TokenSet 1242 | frame.node.edges["*"] = insertionNode 1243 | } 1244 | 1245 | if (frame.str.length == 0) { 1246 | insertionNode.final = true 1247 | } else { 1248 | stack.push({ 1249 | node: insertionNode, 1250 | editsRemaining: frame.editsRemaining - 1, 1251 | str: frame.str 1252 | }) 1253 | } 1254 | } 1255 | 1256 | // transposition 1257 | // can only do a transposition if there are edits remaining 1258 | // and there are enough characters to transpose 1259 | if (frame.editsRemaining > 0 && frame.str.length > 1) { 1260 | var charA = frame.str.charAt(0), 1261 | charB = frame.str.charAt(1), 1262 | transposeNode 1263 | 1264 | if (charB in frame.node.edges) { 1265 | transposeNode = frame.node.edges[charB] 1266 | } else { 1267 | transposeNode = new lunr.TokenSet 1268 | frame.node.edges[charB] = transposeNode 1269 | } 1270 | 1271 | if (frame.str.length == 1) { 1272 | transposeNode.final = true 1273 | } else { 1274 | stack.push({ 1275 | node: transposeNode, 1276 | editsRemaining: frame.editsRemaining - 1, 1277 | str: charA + frame.str.slice(2) 1278 | }) 1279 | } 1280 | } 1281 | } 1282 | 1283 | return root 1284 | } 1285 | 1286 | /** 1287 | * Creates a TokenSet from a string. 1288 | * 1289 | * The string may contain one or more wildcard characters (*) 1290 | * that will allow wildcard matching when intersecting with 1291 | * another TokenSet. 1292 | * 1293 | * @param {string} str - The string to create a TokenSet from. 1294 | * @returns {lunr.TokenSet} 1295 | */ 1296 | lunr.TokenSet.fromString = function (str) { 1297 | var node = new lunr.TokenSet, 1298 | root = node, 1299 | wildcardFound = false 1300 | 1301 | /* 1302 | * Iterates through all characters within the passed string 1303 | * appending a node for each character. 1304 | * 1305 | * As soon as a wildcard character is found then a self 1306 | * referencing edge is introduced to continually match 1307 | * any number of any characters. 1308 | */ 1309 | for (var i = 0, len = str.length; i < len; i++) { 1310 | var char = str[i], 1311 | final = (i == len - 1) 1312 | 1313 | if (char == "*") { 1314 | wildcardFound = true 1315 | node.edges[char] = node 1316 | node.final = final 1317 | 1318 | } else { 1319 | var next = new lunr.TokenSet 1320 | next.final = final 1321 | 1322 | node.edges[char] = next 1323 | node = next 1324 | 1325 | // TODO: is this needed anymore? 1326 | if (wildcardFound) { 1327 | node.edges["*"] = root 1328 | } 1329 | } 1330 | } 1331 | 1332 | return root 1333 | } 1334 | 1335 | /** 1336 | * Converts this TokenSet into an array of strings 1337 | * contained within the TokenSet. 1338 | * 1339 | * @returns {string[]} 1340 | */ 1341 | lunr.TokenSet.prototype.toArray = function () { 1342 | var words = [] 1343 | 1344 | var stack = [{ 1345 | prefix: "", 1346 | node: this 1347 | }] 1348 | 1349 | while (stack.length) { 1350 | var frame = stack.pop(), 1351 | edges = Object.keys(frame.node.edges), 1352 | len = edges.length 1353 | 1354 | if (frame.node.final) { 1355 | words.push(frame.prefix) 1356 | } 1357 | 1358 | for (var i = 0; i < len; i++) { 1359 | var edge = edges[i] 1360 | 1361 | stack.push({ 1362 | prefix: frame.prefix.concat(edge), 1363 | node: frame.node.edges[edge] 1364 | }) 1365 | } 1366 | } 1367 | 1368 | return words 1369 | } 1370 | 1371 | /** 1372 | * Generates a string representation of a TokenSet. 1373 | * 1374 | * This is intended to allow TokenSets to be used as keys 1375 | * in objects, largely to aid the construction and minimisation 1376 | * of a TokenSet. As such it is not designed to be a human 1377 | * friendly representation of the TokenSet. 1378 | * 1379 | * @returns {string} 1380 | */ 1381 | lunr.TokenSet.prototype.toString = function () { 1382 | // NOTE: Using Object.keys here as this.edges is very likely 1383 | // to enter 'hash-mode' with many keys being added 1384 | // 1385 | // avoiding a for-in loop here as it leads to the function 1386 | // being de-optimised (at least in V8). From some simple 1387 | // benchmarks the performance is comparable, but allowing 1388 | // V8 to optimize may mean easy performance wins in the future. 1389 | 1390 | if (this._str) { 1391 | return this._str 1392 | } 1393 | 1394 | var str = this.final ? '1' : '0', 1395 | labels = Object.keys(this.edges), 1396 | len = labels.length 1397 | 1398 | for (var i = 0; i < len; i++) { 1399 | var label = labels[i], 1400 | node = this.edges[label] 1401 | 1402 | str = str + label + node.toString() 1403 | } 1404 | 1405 | return str 1406 | } 1407 | 1408 | /** 1409 | * Returns a new TokenSet that is the intersection of 1410 | * this TokenSet and the passed TokenSet. 1411 | * 1412 | * This intersection will take into account any wildcards 1413 | * contained within the TokenSet. 1414 | * 1415 | * @param {lunr.TokenSet} b - An other TokenSet to intersect with. 1416 | * @returns {lunr.TokenSet} 1417 | */ 1418 | lunr.TokenSet.prototype.intersect = function (b) { 1419 | var output = new lunr.TokenSet, 1420 | frame = undefined 1421 | 1422 | var stack = [{ 1423 | qNode: b, 1424 | output: output, 1425 | node: this 1426 | }] 1427 | 1428 | while (stack.length) { 1429 | frame = stack.pop() 1430 | 1431 | // NOTE: As with the #toString method, we are using 1432 | // Object.keys and a for loop instead of a for-in loop 1433 | // as both of these objects enter 'hash' mode, causing 1434 | // the function to be de-optimised in V8 1435 | var qEdges = Object.keys(frame.qNode.edges), 1436 | qLen = qEdges.length, 1437 | nEdges = Object.keys(frame.node.edges), 1438 | nLen = nEdges.length 1439 | 1440 | for (var q = 0; q < qLen; q++) { 1441 | var qEdge = qEdges[q] 1442 | 1443 | for (var n = 0; n < nLen; n++) { 1444 | var nEdge = nEdges[n] 1445 | 1446 | if (nEdge == qEdge || qEdge == '*') { 1447 | var node = frame.node.edges[nEdge], 1448 | qNode = frame.qNode.edges[qEdge], 1449 | final = node.final && qNode.final, 1450 | next = undefined 1451 | 1452 | if (nEdge in frame.output.edges) { 1453 | // an edge already exists for this character 1454 | // no need to create a new node, just set the finality 1455 | // bit unless this node is already final 1456 | next = frame.output.edges[nEdge] 1457 | next.final = next.final || final 1458 | 1459 | } else { 1460 | // no edge exists yet, must create one 1461 | // set the finality bit and insert it 1462 | // into the output 1463 | next = new lunr.TokenSet 1464 | next.final = final 1465 | frame.output.edges[nEdge] = next 1466 | } 1467 | 1468 | stack.push({ 1469 | qNode: qNode, 1470 | output: next, 1471 | node: node 1472 | }) 1473 | } 1474 | } 1475 | } 1476 | } 1477 | 1478 | return output 1479 | } 1480 | lunr.TokenSet.Builder = function () { 1481 | this.previousWord = "" 1482 | this.root = new lunr.TokenSet 1483 | this.uncheckedNodes = [] 1484 | this.minimizedNodes = {} 1485 | } 1486 | 1487 | lunr.TokenSet.Builder.prototype.insert = function (word) { 1488 | var node, 1489 | commonPrefix = 0 1490 | 1491 | if (word < this.previousWord) { 1492 | throw new Error ("Out of order word insertion") 1493 | } 1494 | 1495 | for (var i = 0; i < word.length && i < this.previousWord.length; i++) { 1496 | if (word[i] != this.previousWord[i]) break 1497 | commonPrefix++ 1498 | } 1499 | 1500 | this.minimize(commonPrefix) 1501 | 1502 | if (this.uncheckedNodes.length == 0) { 1503 | node = this.root 1504 | } else { 1505 | node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child 1506 | } 1507 | 1508 | for (var i = commonPrefix; i < word.length; i++) { 1509 | var nextNode = new lunr.TokenSet, 1510 | char = word[i] 1511 | 1512 | node.edges[char] = nextNode 1513 | 1514 | this.uncheckedNodes.push({ 1515 | parent: node, 1516 | char: char, 1517 | child: nextNode 1518 | }) 1519 | 1520 | node = nextNode 1521 | } 1522 | 1523 | node.final = true 1524 | this.previousWord = word 1525 | } 1526 | 1527 | lunr.TokenSet.Builder.prototype.finish = function () { 1528 | this.minimize(0) 1529 | } 1530 | 1531 | lunr.TokenSet.Builder.prototype.minimize = function (downTo) { 1532 | for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) { 1533 | var node = this.uncheckedNodes[i], 1534 | childKey = node.child.toString() 1535 | 1536 | if (childKey in this.minimizedNodes) { 1537 | node.parent.edges[node.char] = this.minimizedNodes[childKey] 1538 | } else { 1539 | // Cache the key for this node since 1540 | // we know it can't change anymore 1541 | node.child._str = childKey 1542 | 1543 | this.minimizedNodes[childKey] = node.child 1544 | } 1545 | 1546 | this.uncheckedNodes.pop() 1547 | } 1548 | } 1549 | /*! 1550 | * lunr.Index 1551 | * Copyright (C) 2016 Oliver Nightingale 1552 | */ 1553 | 1554 | /** 1555 | * An index contains the built index of all documents and provides a query interface 1556 | * to the index. 1557 | * 1558 | * Usually instances of lunr.Index will not be created using this constructor, instead 1559 | * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be 1560 | * used to load previously built and serialized indexes. 1561 | * 1562 | * @constructor 1563 | * @param {Object} attrs - The attributes of the built search index. 1564 | * @param {Object} attrs.invertedIndex - An index of term/field to document reference. 1565 | * @param {Object} attrs.documentVectors - Document vectors keyed by document reference. 1566 | * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens. 1567 | * @param {number} attrs.documentCount - The total number of documents held in the index. 1568 | * @param {number} attrs.averageDocumentLength - The average length of all documents in the index. 1569 | * @param {number} attrs.b - A parameter for the document scoring algorithm. 1570 | * @param {number} attrs.k1 - A parameter for the document scoring algorithm. 1571 | * @param {string[]} attrs.fields - The names of indexed document fields. 1572 | * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms. 1573 | */ 1574 | lunr.Index = function (attrs) { 1575 | this.invertedIndex = attrs.invertedIndex 1576 | this.documentVectors = attrs.documentVectors 1577 | this.tokenSet = attrs.tokenSet 1578 | this.documentCount = attrs.documentCount 1579 | this.averageDocumentLength = attrs.averageDocumentLength 1580 | this.b = attrs.b 1581 | this.k1 = attrs.k1 1582 | this.fields = attrs.fields 1583 | this.pipeline = attrs.pipeline 1584 | } 1585 | 1586 | /** 1587 | * A result contains details of a document matching a search query. 1588 | * @typedef {Object} lunr.Index~Result 1589 | * @property {string} ref - The reference of the document this result represents. 1590 | * @property {number} score - A number between 0 and 1 representing how similar this document is to the query. 1591 | * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match. 1592 | */ 1593 | 1594 | /** 1595 | * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple 1596 | * query language which itself is parsed into an instance of lunr.Query. 1597 | * 1598 | * For programmatically building queries it is advised to directly use lunr.Query, the query language 1599 | * is best used for human entered text rather than program generated text. 1600 | * 1601 | * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported 1602 | * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello' 1603 | * or 'world', though those that contain both will rank higher in the results. 1604 | * 1605 | * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can 1606 | * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding 1607 | * wildcards will increase the number of documents that will be found but can also have a negative 1608 | * impact on query performance, especially with wildcards at the beginning of a term. 1609 | * 1610 | * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term 1611 | * hello in the title field will match this query. Using a field not present in the index will lead 1612 | * to an error being thrown. 1613 | * 1614 | * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term 1615 | * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported 1616 | * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2. 1617 | * Avoid large values for edit distance to improve query performance. 1618 | * 1619 | * @typedef {string} lunr.Index~QueryString 1620 | * @example Simple single term query 1621 | * hello 1622 | * @example Multiple term query 1623 | * hello world 1624 | * @example term scoped to a field 1625 | * title:hello 1626 | * @example term with a boost of 10 1627 | * hello^10 1628 | * @example term with an edit distance of 2 1629 | * hello~2 1630 | */ 1631 | 1632 | /** 1633 | * Performs a search against the index using lunr query syntax. 1634 | * 1635 | * Results will be returned sorted by their score, the most relevant results 1636 | * will be returned first. 1637 | * 1638 | * For more programmatic querying use lunr.Index#query. 1639 | * 1640 | * @param {lunr.Index~QueryString} queryString - A string containing a lunr query. 1641 | * @throws {lunr.QueryParseError} If the passed query string cannot be parsed. 1642 | * @returns {lunr.Index~Result[]} 1643 | */ 1644 | lunr.Index.prototype.search = function (queryString) { 1645 | return this.query(function (query) { 1646 | var parser = new lunr.QueryParser(queryString, query) 1647 | parser.parse() 1648 | }) 1649 | } 1650 | 1651 | /** 1652 | * A query builder callback provides a query object to be used to express 1653 | * the query to perform on the index. 1654 | * 1655 | * @callback lunr.Index~queryBuilder 1656 | * @param {lunr.Query} query - The query object to build up. 1657 | * @this lunr.Query 1658 | */ 1659 | 1660 | /** 1661 | * Performs a query against the index using the yielded lunr.Query object. 1662 | * 1663 | * If performing programmatic queries against the index, this method is preferred 1664 | * over lunr.Index#search so as to avoid the additional query parsing overhead. 1665 | * 1666 | * A query object is yielded to the supplied function which should be used to 1667 | * express the query to be run against the index. 1668 | * 1669 | * Note that although this function takes a callback parameter it is _not_ an 1670 | * asynchronous operation, the callback is just yielded a query object to be 1671 | * customized. 1672 | * 1673 | * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query. 1674 | * @returns {lunr.Index~Result[]} 1675 | */ 1676 | lunr.Index.prototype.query = function (fn) { 1677 | // for each query clause 1678 | // * process terms 1679 | // * expand terms from token set 1680 | // * find matching documents and metadata 1681 | // * get document vectors 1682 | // * score documents 1683 | 1684 | var query = new lunr.Query(this.fields), 1685 | matchingDocuments = {}, 1686 | queryVector = new lunr.Vector 1687 | 1688 | fn.call(query, query) 1689 | 1690 | for (var i = 0; i < query.clauses.length; i++) { 1691 | /* 1692 | * Unless the pipeline has been disabled for this term, which is 1693 | * the case for terms with wildcards, we need to pass the clause 1694 | * term through the search pipeline. A pipeline returns an array 1695 | * of processed terms. Pipeline functions may expand the passed 1696 | * term, which means we may end up performing multiple index lookups 1697 | * for a single query term. 1698 | */ 1699 | var clause = query.clauses[i], 1700 | terms = null 1701 | 1702 | if (clause.usePipeline) { 1703 | terms = this.pipeline.runString(clause.term) 1704 | } else { 1705 | terms = [clause.term] 1706 | } 1707 | 1708 | for (var m = 0; m < terms.length; m++) { 1709 | var term = terms[m] 1710 | 1711 | /* 1712 | * Each term returned from the pipeline needs to use the same query 1713 | * clause object, e.g. the same boost and or edit distance. The 1714 | * simplest way to do this is to re-use the clause object but mutate 1715 | * its term property. 1716 | */ 1717 | clause.term = term 1718 | 1719 | /* 1720 | * From the term in the clause we create a token set which will then 1721 | * be used to intersect the indexes token set to get a list of terms 1722 | * to lookup in the inverted index 1723 | */ 1724 | var termTokenSet = lunr.TokenSet.fromClause(clause), 1725 | expandedTerms = this.tokenSet.intersect(termTokenSet).toArray() 1726 | 1727 | for (var j = 0; j < expandedTerms.length; j++) { 1728 | /* 1729 | * For each term calculate the score as the term relates to the 1730 | * query using the same calculation used to score documents during 1731 | * indexing. This score will be used to build a vector space 1732 | * representation of the query. 1733 | * 1734 | * Also need to discover the terms index to insert into the query 1735 | * vector at the right position 1736 | */ 1737 | var expandedTerm = expandedTerms[j], 1738 | posting = this.invertedIndex[expandedTerm], 1739 | termIndex = posting._index, 1740 | idf = lunr.idf(posting, this.documentCount), 1741 | tf = 1, 1742 | score = idf * ((this.k1 + 1) * tf) / (this.k1 * (1 - this.b + this.b * (query.clauses.length / this.averageDocumentLength)) + tf) 1743 | 1744 | /* 1745 | * Inserting the found query term, along with its term index 1746 | * into the vector representing the query. It is here that 1747 | * any boosts are applied to the score. They could have been 1748 | * applied when calculating the score above, but that expression 1749 | * is already quite busy. 1750 | */ 1751 | queryVector.insert(termIndex, score * clause.boost) 1752 | 1753 | for (var k = 0; k < clause.fields.length; k++) { 1754 | /* 1755 | * For each field that this query term is scoped by (by default 1756 | * all fields are in scope) we need to get all the document refs 1757 | * that have this term in that field. 1758 | * 1759 | * The posting is the entry in the invertedIndex for the matching 1760 | * term from above. 1761 | */ 1762 | var field = clause.fields[k], 1763 | fieldPosting = posting[field], 1764 | matchingDocumentRefs = Object.keys(fieldPosting) 1765 | 1766 | for (var l = 0; l < matchingDocumentRefs.length; l++) { 1767 | /* 1768 | * All metadata for this term/field/document triple 1769 | * are then extracted and collected into an instance 1770 | * of lunr.MatchData ready to be returned in the query 1771 | * results 1772 | */ 1773 | var matchingDocumentRef = matchingDocumentRefs[l], 1774 | documentMetadata, matchData 1775 | 1776 | documentMetadata = fieldPosting[matchingDocumentRef] 1777 | matchData = new lunr.MatchData (expandedTerm, field, documentMetadata) 1778 | 1779 | if (matchingDocumentRef in matchingDocuments) { 1780 | matchingDocuments[matchingDocumentRef].combine(matchData) 1781 | } else { 1782 | matchingDocuments[matchingDocumentRef] = matchData 1783 | } 1784 | 1785 | } 1786 | } 1787 | } 1788 | } 1789 | } 1790 | 1791 | var matchingDocumentRefs = Object.keys(matchingDocuments), 1792 | results = [] 1793 | 1794 | for (var i = 0; i < matchingDocumentRefs.length; i++) { 1795 | /* 1796 | * With all the matching documents found they now need 1797 | * to be sorted by their relevance to the query. This 1798 | * is done by retrieving the documents vector representation 1799 | * and then finding its similarity with the query vector 1800 | * that was constructed earlier. 1801 | * 1802 | * This score, along with the document ref and any metadata 1803 | * we collected into a lunr.MatchData instance are stored 1804 | * in the results array ready for returning to the caller 1805 | */ 1806 | var ref = matchingDocumentRefs[i], 1807 | documentVector = this.documentVectors[ref], 1808 | score = queryVector.similarity(documentVector) 1809 | 1810 | results.push({ 1811 | ref: ref, 1812 | score: score, 1813 | matchData: matchingDocuments[ref] 1814 | }) 1815 | } 1816 | 1817 | return results.sort(function (a, b) { 1818 | return b.score - a.score 1819 | }) 1820 | } 1821 | 1822 | /** 1823 | * Prepares the index for JSON serialization. 1824 | * 1825 | * The schema for this JSON blob will be described in a 1826 | * separate JSON schema file. 1827 | * 1828 | * @returns {Object} 1829 | */ 1830 | lunr.Index.prototype.toJSON = function () { 1831 | var invertedIndex = Object.keys(this.invertedIndex) 1832 | .sort() 1833 | .map(function (term) { 1834 | return [term, this.invertedIndex[term]] 1835 | }, this) 1836 | 1837 | var documentVectors = Object.keys(this.documentVectors) 1838 | .map(function (ref) { 1839 | return [ref, this.documentVectors[ref].toJSON()] 1840 | }, this) 1841 | 1842 | return { 1843 | version: lunr.version, 1844 | averageDocumentLength: this.averageDocumentLength, 1845 | b: this.b, 1846 | k1: this.k1, 1847 | fields: this.fields, 1848 | documentVectors: documentVectors, 1849 | invertedIndex: invertedIndex, 1850 | pipeline: this.pipeline.toJSON() 1851 | } 1852 | } 1853 | 1854 | /** 1855 | * Loads a previously serialized lunr.Index 1856 | * 1857 | * @param {Object} serializedIndex - A previously serialized lunr.Index 1858 | * @returns {lunr.Index} 1859 | */ 1860 | lunr.Index.load = function (serializedIndex) { 1861 | var attrs = {}, 1862 | documentVectors = {}, 1863 | serializedVectors = serializedIndex.documentVectors, 1864 | documentCount = 0, 1865 | invertedIndex = {}, 1866 | serializedInvertedIndex = serializedIndex.invertedIndex, 1867 | tokenSetBuilder = new lunr.TokenSet.Builder, 1868 | pipeline = lunr.Pipeline.load(serializedIndex.pipeline) 1869 | 1870 | if (serializedIndex.version != lunr.version) { 1871 | lunr.utils.warn("Version mismatch when loading serialised index. Current version of lunr '" + lunr.version + "' does not match serialized index '" + serializedIndex.version + "'") 1872 | } 1873 | 1874 | for (var i = 0; i < serializedVectors.length; i++, documentCount++) { 1875 | var tuple = serializedVectors[i], 1876 | ref = tuple[0], 1877 | elements = tuple[1] 1878 | 1879 | documentVectors[ref] = new lunr.Vector(elements) 1880 | } 1881 | 1882 | for (var i = 0; i < serializedInvertedIndex.length; i++) { 1883 | var tuple = serializedInvertedIndex[i], 1884 | term = tuple[0], 1885 | posting = tuple[1] 1886 | 1887 | tokenSetBuilder.insert(term) 1888 | invertedIndex[term] = posting 1889 | } 1890 | 1891 | tokenSetBuilder.finish() 1892 | 1893 | attrs.b = serializedIndex.b 1894 | attrs.k1 = serializedIndex.k1 1895 | attrs.fields = serializedIndex.fields 1896 | attrs.averageDocumentLength = serializedIndex.averageDocumentLength 1897 | 1898 | attrs.documentCount = documentCount 1899 | attrs.documentVectors = documentVectors 1900 | attrs.invertedIndex = invertedIndex 1901 | attrs.tokenSet = tokenSetBuilder.root 1902 | attrs.pipeline = pipeline 1903 | 1904 | return new lunr.Index(attrs) 1905 | } 1906 | /*! 1907 | * lunr.Builder 1908 | * Copyright (C) 2016 Oliver Nightingale 1909 | */ 1910 | 1911 | /** 1912 | * lunr.Builder performs indexing on a set of documents and 1913 | * returns instances of lunr.Index ready for querying. 1914 | * 1915 | * All configuration of the index is done via the builder, the 1916 | * fields to index, the document reference, the text processing 1917 | * pipeline and document scoring parameters are all set on the 1918 | * builder before indexing. 1919 | * 1920 | * @constructor 1921 | * @property {string} _ref - Internal reference to the document reference field. 1922 | * @property {string[]} _fields - Internal reference to the document fields to index. 1923 | * @property {object} invertedIndex - The inverted index maps terms to document fields. 1924 | * @property {object} documentTermFrequencies - ??? 1925 | * @property {object} documentLengths - ??? 1926 | * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing. 1927 | * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing. 1928 | * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index. 1929 | * @property {number} documentCount - Keeps track of the total number of documents indexed. 1930 | * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75. 1931 | * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2. 1932 | * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space. 1933 | * @property {array} metadataWhitelist - ??? 1934 | */ 1935 | lunr.Builder = function () { 1936 | this._ref = "id" 1937 | this._fields = [] 1938 | this.invertedIndex = {} 1939 | this.documentTermFrequencies = {} 1940 | this.documentLengths = {} 1941 | this.tokenizer = lunr.tokenizer 1942 | this.pipeline = new lunr.Pipeline 1943 | this.searchPipeline = new lunr.Pipeline 1944 | this.documentCount = 0 1945 | this._b = 0.75 1946 | this._k1 = 1.2 1947 | this.termIndex = 0 1948 | this.metadataWhitelist = [] 1949 | } 1950 | 1951 | /** 1952 | * Sets the document field used as the document reference. Every document must have this field. 1953 | * The type of this field in the document should be a string, if it is not a string it will be 1954 | * coerced into a string by calling toString. 1955 | * 1956 | * The default ref is 'id'. 1957 | * 1958 | * The ref should _not_ be changed during indexing, it should be set before any documents are 1959 | * added to the index. Changing it during indexing can lead to inconsistent results. 1960 | * 1961 | * @param {string} ref - The name of the reference field in the document. 1962 | */ 1963 | lunr.Builder.prototype.ref = function (ref) { 1964 | this._ref = ref 1965 | } 1966 | 1967 | /** 1968 | * Adds a field to the list of document fields that will be indexed. Every document being 1969 | * indexed should have this field. Null values for this field in indexed documents will 1970 | * not cause errors but will limit the chance of that document being retrieved by searches. 1971 | * 1972 | * All fields should be added before adding documents to the index. Adding fields after 1973 | * a document has been indexed will have no effect on already indexed documents. 1974 | * 1975 | * @param {string} field - The name of a field to index in all documents. 1976 | */ 1977 | lunr.Builder.prototype.field = function (field) { 1978 | this._fields.push(field) 1979 | } 1980 | 1981 | /** 1982 | * A parameter to tune the amount of field length normalisation that is applied when 1983 | * calculating relevance scores. A value of 0 will completely disable any normalisation 1984 | * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b 1985 | * will be clamped to the range 0 - 1. 1986 | * 1987 | * @param {number} number - The value to set for this tuning parameter. 1988 | */ 1989 | lunr.Builder.prototype.b = function (number) { 1990 | if (number < 0) { 1991 | this._b = 0 1992 | } else if (number > 1) { 1993 | this._b = 1 1994 | } else { 1995 | this._b = number 1996 | } 1997 | } 1998 | 1999 | /** 2000 | * A parameter that controls the speed at which a rise in term frequency results in term 2001 | * frequency saturation. The default value is 1.2. Setting this to a higher value will give 2002 | * slower saturation levels, a lower value will result in quicker saturation. 2003 | * 2004 | * @param {number} number - The value to set for this tuning parameter. 2005 | */ 2006 | lunr.Builder.prototype.k1 = function (number) { 2007 | this._k1 = number 2008 | } 2009 | 2010 | /** 2011 | * Adds a document to the index. 2012 | * 2013 | * Before adding fields to the index the index should have been fully setup, with the document 2014 | * ref and all fields to index already having been specified. 2015 | * 2016 | * The document must have a field name as specified by the ref (by default this is 'id') and 2017 | * it should have all fields defined for indexing, though null or undefined values will not 2018 | * cause errors. 2019 | * 2020 | * @param {object} doc - The document to add to the index. 2021 | */ 2022 | lunr.Builder.prototype.add = function (doc) { 2023 | var docRef = doc[this._ref], 2024 | documentTerms = {} 2025 | 2026 | this.documentCount += 1 2027 | this.documentTermFrequencies[docRef] = documentTerms 2028 | this.documentLengths[docRef] = 0 2029 | 2030 | for (var i = 0; i < this._fields.length; i++) { 2031 | var fieldName = this._fields[i], 2032 | field = doc[fieldName], 2033 | tokens = this.tokenizer(field), 2034 | terms = this.pipeline.run(tokens) 2035 | 2036 | // store the length of this field for this document 2037 | this.documentLengths[docRef] += terms.length 2038 | 2039 | // calculate term frequencies for this field 2040 | for (var j = 0; j < terms.length; j++) { 2041 | var term = terms[j] 2042 | 2043 | if (documentTerms[term] == undefined) { 2044 | documentTerms[term] = 0 2045 | } 2046 | 2047 | documentTerms[term] += 1 2048 | 2049 | // add to inverted index 2050 | // create an initial posting if one doesn't exist 2051 | if (this.invertedIndex[term] == undefined) { 2052 | var posting = { "_index": this.termIndex } 2053 | this.termIndex += 1 2054 | 2055 | for (var k = 0; k < this._fields.length; k++) { 2056 | posting[this._fields[k]] = {} 2057 | } 2058 | 2059 | this.invertedIndex[term] = posting 2060 | } 2061 | 2062 | // add an entry for this term/fieldName/docRef to the invertedIndex 2063 | if (this.invertedIndex[term][fieldName][docRef] == undefined) { 2064 | this.invertedIndex[term][fieldName][docRef] = {} 2065 | } 2066 | 2067 | // store all whitelisted metadata about this token in the 2068 | // inverted index 2069 | for (var l = 0; l < this.metadataWhitelist.length; l++) { 2070 | var metadataKey = this.metadataWhitelist[l], 2071 | metadata = term.metadata[metadataKey] 2072 | 2073 | if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) { 2074 | this.invertedIndex[term][fieldName][docRef][metadataKey] = [] 2075 | } 2076 | 2077 | this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata) 2078 | } 2079 | } 2080 | 2081 | } 2082 | } 2083 | 2084 | /** 2085 | * Calculates the average document length for this index 2086 | * 2087 | * @private 2088 | */ 2089 | lunr.Builder.prototype.calculateAverageDocumentLengths = function () { 2090 | 2091 | var documentRefs = Object.keys(this.documentLengths), 2092 | numberOfDocuments = documentRefs.length, 2093 | allDocumentsLength = 0 2094 | 2095 | for (var i = 0; i < numberOfDocuments; i++) { 2096 | var documentRef = documentRefs[i] 2097 | allDocumentsLength += this.documentLengths[documentRef] 2098 | } 2099 | 2100 | this.averageDocumentLength = allDocumentsLength / numberOfDocuments 2101 | } 2102 | 2103 | /** 2104 | * Builds a vector space model of every document using lunr.Vector 2105 | * 2106 | * @private 2107 | */ 2108 | lunr.Builder.prototype.createDocumentVectors = function () { 2109 | var documentVectors = {}, 2110 | docRefs = Object.keys(this.documentTermFrequencies), 2111 | docRefsLength = docRefs.length 2112 | 2113 | for (var i = 0; i < docRefsLength; i++) { 2114 | var docRef = docRefs[i], 2115 | documentLength = this.documentLengths[docRef], 2116 | documentVector = new lunr.Vector, 2117 | termFrequencies = this.documentTermFrequencies[docRef], 2118 | terms = Object.keys(termFrequencies), 2119 | termsLength = terms.length 2120 | 2121 | for (var j = 0; j < termsLength; j++) { 2122 | var term = terms[j], 2123 | tf = termFrequencies[term], 2124 | termIndex = this.invertedIndex[term]._index, 2125 | idf = lunr.idf(this.invertedIndex[term], this.documentCount), 2126 | score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (documentLength / this.averageDocumentLength)) + tf) 2127 | 2128 | documentVector.insert(termIndex, score) 2129 | } 2130 | 2131 | documentVectors[docRef] = documentVector 2132 | } 2133 | 2134 | this.documentVectors = documentVectors 2135 | } 2136 | 2137 | /** 2138 | * Creates a token set of all tokens in the index using lunr.TokenSet 2139 | * 2140 | * @private 2141 | */ 2142 | lunr.Builder.prototype.createTokenSet = function () { 2143 | this.tokenSet = lunr.TokenSet.fromArray( 2144 | Object.keys(this.invertedIndex).sort() 2145 | ) 2146 | } 2147 | 2148 | /** 2149 | * Builds the index, creating an instance of lunr.Index. 2150 | * 2151 | * This completes the indexing process and should only be called 2152 | * once all documents have been added to the index. 2153 | * 2154 | * @private 2155 | * @returns {lunr.Index} 2156 | */ 2157 | lunr.Builder.prototype.build = function () { 2158 | this.calculateAverageDocumentLengths() 2159 | this.createDocumentVectors() 2160 | this.createTokenSet() 2161 | 2162 | return new lunr.Index({ 2163 | invertedIndex: this.invertedIndex, 2164 | documentVectors: this.documentVectors, 2165 | tokenSet: this.tokenSet, 2166 | averageDocumentLength: this.averageDocumentLength, 2167 | documentCount: this.documentCount, 2168 | fields: this._fields, 2169 | pipeline: this.searchPipeline, 2170 | b: this._b, 2171 | k1: this._k1 2172 | }) 2173 | } 2174 | /** 2175 | * Contains and collects metadata about a matching document. 2176 | * A single instance of lunr.MatchData is returned as part of every 2177 | * lunr.Index~Result. 2178 | * 2179 | * @constructor 2180 | * @property {string[]} terms - All the query terms that the document matched. 2181 | * @property {object} metadata - A collection of metadata associated with this document. 2182 | * @see {@link lunr.Index~Result} 2183 | */ 2184 | lunr.MatchData = function (term, field, metadata) { 2185 | this.terms = [term] 2186 | 2187 | this.metadata = {} 2188 | this.metadata[field] = metadata 2189 | } 2190 | 2191 | /** 2192 | * An instance of lunr.MatchData will be created for every term that matches a 2193 | * document. However only one instance is required in a lunr.Index~Result. This 2194 | * method combines metadata from another instance of lunr.MatchData with this 2195 | * objects metadata. 2196 | * 2197 | * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one. 2198 | * @see {@link lunr.Index~Result} 2199 | */ 2200 | lunr.MatchData.prototype.combine = function (otherMatchData) { 2201 | this.terms = this.terms.concat(otherMatchData.terms) 2202 | 2203 | var otherMatchDataFields = Object.keys(otherMatchData.metadata) 2204 | 2205 | for (var i = 0; i < otherMatchDataFields.length; i++) { 2206 | var field = otherMatchDataFields[i], 2207 | fieldMetadata = otherMatchData.metadata[field], 2208 | fieldMetadataKeys = Object.keys(fieldMetadata) 2209 | 2210 | if (this.metadata[field] == undefined) { 2211 | this.metadata[field] = {} 2212 | } 2213 | 2214 | for (var j = 0; j < fieldMetadataKeys.length; j++) { 2215 | var metadataKey = fieldMetadataKeys[j] 2216 | 2217 | if (this.metadata[field][metadataKey] == undefined) { 2218 | this.metadata[field][metadataKey] = fieldMetadata[metadataKey] 2219 | } else { 2220 | this.metadata[field][metadataKey] = this.metadata[field][metadataKey].concat(fieldMetadata[metadataKey]) 2221 | } 2222 | } 2223 | } 2224 | } 2225 | /** 2226 | * A lunr.Query provides a programmatic way of defining queries to be performed 2227 | * against a {@link lunr.Index}. 2228 | * 2229 | * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method 2230 | * so the query object is pre-initialized with the right index fields. 2231 | * 2232 | * @constructor 2233 | * @property {lunr.Query~Clause[]} clauses - An array of query clauses. 2234 | * @property {string[]} allFields - An array of all available fields in a lunr.Index. 2235 | */ 2236 | lunr.Query = function (allFields) { 2237 | this.clauses = [] 2238 | this.allFields = allFields 2239 | } 2240 | 2241 | /** 2242 | * A single clause in a {@link lunr.Query} contains a term and details on how to 2243 | * match that term against a {@link lunr.Index}. 2244 | * 2245 | * @typedef {Object} lunr.Query~Clause 2246 | * @property {string[]} fields - The fields in an index this clause should be matched against. 2247 | * @property {number} boost - Any boost that should be applied when matching this clause. 2248 | * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be. 2249 | * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline. 2250 | */ 2251 | 2252 | /** 2253 | * Adds a {@link lunr.Query~Clause} to this query. 2254 | * 2255 | * Unless the clause contains the fields to be matched all fields will be matched. In addition 2256 | * a default boost of 1 is applied to the clause. 2257 | * 2258 | * @param {lunr.Query~Clause} clause - The clause to add to this query. 2259 | * @returns {lunr.Query} 2260 | */ 2261 | lunr.Query.prototype.clause = function (clause) { 2262 | if (!('fields' in clause)) { 2263 | clause.fields = this.allFields 2264 | } 2265 | 2266 | if (!('boost' in clause)) { 2267 | clause.boost = 1 2268 | } 2269 | 2270 | if (!('usePipeline' in clause)) { 2271 | clause.usePipeline = true 2272 | } 2273 | 2274 | this.clauses.push(clause) 2275 | 2276 | return this 2277 | } 2278 | 2279 | /** 2280 | * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause} 2281 | * to the list of clauses that make up this query. 2282 | * 2283 | * @param {string} term - The term to add to the query. 2284 | * @param {Object} [options] - Any additional properties to add to the query clause. 2285 | * @returns {lunr.Query} 2286 | */ 2287 | lunr.Query.prototype.term = function (term, options) { 2288 | var clause = options || {} 2289 | clause.term = term 2290 | 2291 | this.clause(clause) 2292 | 2293 | return this 2294 | } 2295 | lunr.QueryParseError = function (message, start, end) { 2296 | this.name = "QueryParseError" 2297 | this.message = message 2298 | this.start = start 2299 | this.end = end 2300 | } 2301 | 2302 | lunr.QueryParseError.prototype = new Error 2303 | lunr.QueryLexer = function (str) { 2304 | this.lexemes = [] 2305 | this.str = str 2306 | this.length = str.length 2307 | this.pos = 0 2308 | this.start = 0 2309 | } 2310 | 2311 | lunr.QueryLexer.prototype.run = function () { 2312 | var state = lunr.QueryLexer.lexText 2313 | 2314 | while (state) { 2315 | state = state(this) 2316 | } 2317 | } 2318 | 2319 | lunr.QueryLexer.prototype.emit = function (type) { 2320 | this.lexemes.push({ 2321 | type: type, 2322 | str: this.str.slice(this.start, this.pos), 2323 | start: this.start, 2324 | end: this.pos 2325 | }) 2326 | 2327 | this.start = this.pos 2328 | } 2329 | 2330 | lunr.QueryLexer.prototype.next = function () { 2331 | if (this.pos == this.length) { 2332 | return lunr.QueryLexer.EOS 2333 | } 2334 | 2335 | var char = this.str.charAt(this.pos) 2336 | this.pos += 1 2337 | return char 2338 | } 2339 | 2340 | lunr.QueryLexer.prototype.width = function () { 2341 | return this.pos - this.start 2342 | } 2343 | 2344 | lunr.QueryLexer.prototype.ignore = function () { 2345 | if (this.start == this.pos) { 2346 | this.pos += 1 2347 | } 2348 | 2349 | this.start = this.pos 2350 | } 2351 | 2352 | lunr.QueryLexer.prototype.backup = function () { 2353 | this.pos -= 1 2354 | } 2355 | 2356 | lunr.QueryLexer.prototype.acceptDigitRun = function () { 2357 | var char, charCode 2358 | 2359 | do { 2360 | char = this.next() 2361 | charCode = char.charCodeAt(0) 2362 | } while (charCode > 47 && charCode < 58) 2363 | 2364 | if (char != lunr.QueryLexer.EOS) { 2365 | this.backup() 2366 | } 2367 | } 2368 | 2369 | lunr.QueryLexer.prototype.more = function () { 2370 | return this.pos < this.length 2371 | } 2372 | 2373 | lunr.QueryLexer.EOS = 'EOS' 2374 | lunr.QueryLexer.FIELD = 'FIELD' 2375 | lunr.QueryLexer.TERM = 'TERM' 2376 | lunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE' 2377 | lunr.QueryLexer.BOOST = 'BOOST' 2378 | 2379 | lunr.QueryLexer.lexField = function (lexer) { 2380 | lexer.backup() 2381 | lexer.emit(lunr.QueryLexer.FIELD) 2382 | lexer.ignore() 2383 | return lunr.QueryLexer.lexText 2384 | } 2385 | 2386 | lunr.QueryLexer.lexTerm = function (lexer) { 2387 | if (lexer.width() > 1) { 2388 | lexer.backup() 2389 | lexer.emit(lunr.QueryLexer.TERM) 2390 | } 2391 | 2392 | lexer.ignore() 2393 | 2394 | if (lexer.more()) { 2395 | return lunr.QueryLexer.lexText 2396 | } 2397 | } 2398 | 2399 | lunr.QueryLexer.lexEditDistance = function (lexer) { 2400 | lexer.ignore() 2401 | lexer.acceptDigitRun() 2402 | lexer.emit(lunr.QueryLexer.EDIT_DISTANCE) 2403 | return lunr.QueryLexer.lexText 2404 | } 2405 | 2406 | lunr.QueryLexer.lexBoost = function (lexer) { 2407 | lexer.ignore() 2408 | lexer.acceptDigitRun() 2409 | lexer.emit(lunr.QueryLexer.BOOST) 2410 | return lunr.QueryLexer.lexText 2411 | } 2412 | 2413 | lunr.QueryLexer.lexEOS = function (lexer) { 2414 | if (lexer.width() > 0) { 2415 | lexer.emit(lunr.QueryLexer.TERM) 2416 | } 2417 | } 2418 | 2419 | lunr.QueryLexer.lexText = function (lexer) { 2420 | while (true) { 2421 | var char = lexer.next() 2422 | 2423 | if (char == lunr.QueryLexer.EOS) { 2424 | return lunr.QueryLexer.lexEOS 2425 | } 2426 | 2427 | if (char == ":") { 2428 | return lunr.QueryLexer.lexField 2429 | } 2430 | 2431 | if (char == "~") { 2432 | lexer.backup() 2433 | if (lexer.width() > 0) { 2434 | lexer.emit(lunr.QueryLexer.TERM) 2435 | } 2436 | return lunr.QueryLexer.lexEditDistance 2437 | } 2438 | 2439 | if (char == "^") { 2440 | lexer.backup() 2441 | if (lexer.width() > 0) { 2442 | lexer.emit(lunr.QueryLexer.TERM) 2443 | } 2444 | return lunr.QueryLexer.lexBoost 2445 | } 2446 | 2447 | // TODO: there may be more separators we want to consider 2448 | if (char == " ") { 2449 | return lunr.QueryLexer.lexTerm 2450 | } 2451 | } 2452 | } 2453 | 2454 | lunr.QueryParser = function (str, query) { 2455 | this.lexer = new lunr.QueryLexer (str) 2456 | this.query = query 2457 | this.currentClause = {} 2458 | this.lexemeIdx = 0 2459 | } 2460 | 2461 | lunr.QueryParser.prototype.parse = function () { 2462 | this.lexer.run() 2463 | this.lexemes = this.lexer.lexemes 2464 | 2465 | var state = lunr.QueryParser.parseFieldOrTerm 2466 | 2467 | while (state) { 2468 | state = state(this) 2469 | } 2470 | 2471 | return this.query 2472 | } 2473 | 2474 | lunr.QueryParser.prototype.peekLexeme = function () { 2475 | return this.lexemes[this.lexemeIdx] 2476 | } 2477 | 2478 | lunr.QueryParser.prototype.consumeLexeme = function () { 2479 | var lexeme = this.peekLexeme() 2480 | this.lexemeIdx += 1 2481 | return lexeme 2482 | } 2483 | 2484 | lunr.QueryParser.prototype.nextClause = function () { 2485 | var completedClause = this.currentClause 2486 | this.query.clause(completedClause) 2487 | this.currentClause = {} 2488 | } 2489 | 2490 | lunr.QueryParser.parseFieldOrTerm = function (parser) { 2491 | var lexeme = parser.peekLexeme() 2492 | 2493 | if (lexeme == undefined) { 2494 | return 2495 | } 2496 | 2497 | switch (lexeme.type) { 2498 | case lunr.QueryLexer.FIELD: 2499 | return lunr.QueryParser.parseField 2500 | case lunr.QueryLexer.TERM: 2501 | return lunr.QueryParser.parseTerm 2502 | default: 2503 | var errorMessage = "expected either a field or a term, found " + lexeme.type + " with value '" + lexeme.str + "'" 2504 | throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) 2505 | } 2506 | } 2507 | 2508 | lunr.QueryParser.parseField = function (parser) { 2509 | var lexeme = parser.consumeLexeme() 2510 | 2511 | if (lexeme == undefined) { 2512 | return 2513 | } 2514 | 2515 | if (parser.query.allFields.indexOf(lexeme.str) == -1) { 2516 | var possibleFields = parser.query.allFields.map(function (f) { return "'" + f + "'" }).join(), 2517 | errorMessage = "unrecognised field '" + lexeme.str + "', possible fields: " + possibleFields 2518 | 2519 | throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) 2520 | } 2521 | 2522 | parser.currentClause.fields = [lexeme.str] 2523 | 2524 | var nextLexeme = parser.peekLexeme() 2525 | 2526 | if (nextLexeme == undefined) { 2527 | var errorMessage = "expecting term, found nothing" 2528 | throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) 2529 | } 2530 | 2531 | switch (nextLexeme.type) { 2532 | case lunr.QueryLexer.TERM: 2533 | return lunr.QueryParser.parseTerm 2534 | default: 2535 | var errorMessage = "expecting a field, found '" + nextLexeme.type + "'" 2536 | throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) 2537 | } 2538 | } 2539 | 2540 | lunr.QueryParser.parseTerm = function (parser) { 2541 | var lexeme = parser.consumeLexeme() 2542 | 2543 | if (lexeme == undefined) { 2544 | return 2545 | } 2546 | 2547 | parser.currentClause.term = lexeme.str 2548 | 2549 | if (lexeme.str.indexOf("*") != -1) { 2550 | parser.currentClause.usePipeline = false 2551 | } 2552 | 2553 | var nextLexeme = parser.peekLexeme() 2554 | 2555 | if (nextLexeme == undefined) { 2556 | parser.nextClause() 2557 | return 2558 | } 2559 | 2560 | switch (nextLexeme.type) { 2561 | case lunr.QueryLexer.TERM: 2562 | parser.nextClause() 2563 | return lunr.QueryParser.parseTerm 2564 | case lunr.QueryLexer.FIELD: 2565 | parser.nextClause() 2566 | return lunr.QueryParser.parseField 2567 | case lunr.QueryLexer.EDIT_DISTANCE: 2568 | return lunr.QueryParser.parseEditDistance 2569 | case lunr.QueryLexer.BOOST: 2570 | return lunr.QueryParser.parseBoost 2571 | default: 2572 | var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" 2573 | throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) 2574 | } 2575 | } 2576 | 2577 | lunr.QueryParser.parseEditDistance = function (parser) { 2578 | var lexeme = parser.consumeLexeme() 2579 | 2580 | if (lexeme == undefined) { 2581 | return 2582 | } 2583 | 2584 | var editDistance = parseInt(lexeme.str, 10) 2585 | 2586 | if (isNaN(editDistance)) { 2587 | var errorMessage = "edit distance must be numeric, found '" + lexeme.str + "'" 2588 | throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) 2589 | } 2590 | 2591 | parser.currentClause.editDistance = editDistance 2592 | 2593 | var nextLexeme = parser.peekLexeme() 2594 | 2595 | if (nextLexeme == undefined) { 2596 | parser.nextClause() 2597 | return 2598 | } 2599 | 2600 | switch (nextLexeme.type) { 2601 | case lunr.QueryLexer.TERM: 2602 | parser.nextClause() 2603 | return lunr.QueryParser.parseTerm 2604 | case lunr.QueryLexer.FIELD: 2605 | parser.nextClause() 2606 | return lunr.QueryParser.parseField 2607 | case lunr.QueryLexer.EDIT_DISTANCE: 2608 | return lunr.QueryParser.parseEditDistance 2609 | case lunr.QueryLexer.BOOST: 2610 | return lunr.QueryParser.parseBoost 2611 | default: 2612 | var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" 2613 | throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) 2614 | } 2615 | } 2616 | 2617 | lunr.QueryParser.parseBoost = function (parser) { 2618 | var lexeme = parser.consumeLexeme() 2619 | 2620 | if (lexeme == undefined) { 2621 | return 2622 | } 2623 | 2624 | var boost = parseInt(lexeme.str, 10) 2625 | 2626 | if (isNaN(boost)) { 2627 | var errorMessage = "boost must be numeric, found '" + lexeme.str + "'" 2628 | throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) 2629 | } 2630 | 2631 | parser.currentClause.boost = boost 2632 | 2633 | var nextLexeme = parser.peekLexeme() 2634 | 2635 | if (nextLexeme == undefined) { 2636 | parser.nextClause() 2637 | return 2638 | } 2639 | 2640 | switch (nextLexeme.type) { 2641 | case lunr.QueryLexer.TERM: 2642 | parser.nextClause() 2643 | return lunr.QueryParser.parseTerm 2644 | case lunr.QueryLexer.FIELD: 2645 | parser.nextClause() 2646 | return lunr.QueryParser.parseField 2647 | case lunr.QueryLexer.EDIT_DISTANCE: 2648 | return lunr.QueryParser.parseEditDistance 2649 | case lunr.QueryLexer.BOOST: 2650 | return lunr.QueryParser.parseBoost 2651 | default: 2652 | var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" 2653 | throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) 2654 | } 2655 | } 2656 | 2657 | /** 2658 | * export the module via AMD, CommonJS or as a browser global 2659 | * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js 2660 | */ 2661 | ;(function (root, factory) { 2662 | if (typeof define === 'function' && define.amd) { 2663 | // AMD. Register as an anonymous module. 2664 | define(factory) 2665 | } else if (typeof exports === 'object') { 2666 | /** 2667 | * Node. Does not work with strict CommonJS, but 2668 | * only CommonJS-like enviroments that support module.exports, 2669 | * like Node. 2670 | */ 2671 | module.exports = factory() 2672 | } else { 2673 | // Browser globals (root is window) 2674 | root.lunr = factory() 2675 | } 2676 | }(this, function () { 2677 | /** 2678 | * Just return a value to define the module export. 2679 | * This example returns an object, but the module 2680 | * can return a function as the exported value. 2681 | */ 2682 | return lunr 2683 | })) 2684 | })(); 2685 | --------------------------------------------------------------------------------