├── .gitignore ├── .rspec ├── .travis.yml ├── Gemfile ├── Guardfile ├── LICENSE ├── README.md ├── Rakefile ├── app ├── assets │ ├── images │ │ └── .keep │ ├── javascripts │ │ └── application.js │ └── stylesheets │ │ └── application.css ├── controllers │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ ├── dataset_controller.rb │ └── subject_controller.rb ├── helpers │ └── application_helper.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ └── setting.rb └── views │ └── layouts │ └── application.html.erb ├── bin ├── bundle ├── rails ├── rake ├── setup └── spring ├── circle.yml ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── jetty.yml.sample ├── ldf.yml.sample_blazegraph ├── ldf.yml.sample_marmotta ├── ldf.yml.sample_repository ├── locales │ └── en.yml ├── routes.rb └── secrets.yml ├── db └── seeds.rb ├── lib ├── assets │ └── .keep ├── linked_data_fragments.rb ├── linked_data_fragments │ ├── backend_base.rb │ ├── blazegraph.rb │ ├── builders.rb │ ├── builders │ │ ├── control_builder.rb │ │ ├── dataset_builder.rb │ │ └── template_builder.rb │ ├── hydra_template.rb │ ├── marmotta.rb │ ├── models.rb │ ├── models │ │ ├── control.rb │ │ ├── dataset.rb │ │ ├── result.rb │ │ └── template.rb │ ├── repository.rb │ ├── schemas.rb │ ├── schemas │ │ ├── control_schema.rb │ │ ├── dataset_schema.rb │ │ ├── result_schema.rb │ │ └── template_schema.rb │ ├── service.rb │ └── settings.rb └── tasks │ └── .keep ├── log └── .keep ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico └── robots.txt ├── spec ├── caching │ ├── blazegraph_spec.rb │ ├── marmotta_spec.rb │ └── repository_spec.rb ├── cassettes │ ├── LinkedDataFragments_Blazegraph │ │ └── retrieve_a_subject_uri │ │ │ ├── should_be_configured_as_a_Blazegraph_instance_with_the_mocked_uri.yml │ │ │ └── should_retrieve_and_return_a_response_on_a_valid_subject_uri.yml │ ├── LinkedDataFragments_Marmotta │ │ └── retrieve_a_subject_uri │ │ │ ├── should_be_configured_as_a_Marmotta_instance_with_the_mocked_uri.yml │ │ │ ├── should_retrieve_and_return_a_response_on_a_valid_subject_uri.yml │ │ │ └── should_retrieve_nothing_on_an_invalid_uri.yml │ ├── LinkedDataFragments_Repository │ │ ├── behaves_like_a_backend │ │ │ ├── _add │ │ │ │ └── adds_a_url.yml │ │ │ ├── _delete_all_ │ │ │ │ ├── empties_backend.yml │ │ │ │ └── removes_resources.yml │ │ │ ├── _empty_ │ │ │ │ └── becomes_non-empty_when_a_resource_is_added.yml │ │ │ ├── _has_ │ │ │ │ └── has_a_resource_that_has_been_added.yml │ │ │ └── _retrieve │ │ │ │ ├── when_empty │ │ │ │ ├── loads_a_valid_URL.yml │ │ │ │ └── raises_on_invalid_URL.yml │ │ │ │ └── with_an_existing_resource │ │ │ │ ├── gets_an_RDF_Enumerable.yml │ │ │ │ └── raises_IOError_on_invalid_URL.yml │ │ └── retrieve_a_subject_uri │ │ │ ├── should_retrieve_and_return_a_response_on_a_valid_subject_uri.yml │ │ │ └── should_retrieve_nothing_on_an_invalid_uri.yml │ └── SubjectController │ │ └── subject │ │ └── JSON-LD │ │ └── should_return_a_graph.yml ├── controllers │ ├── dataset_controller_spec.rb │ └── subject_controller_spec.rb ├── linked_data_fragments │ ├── builders │ │ ├── control_builder_spec.rb │ │ ├── dataset_builder_spec.rb │ │ └── template_builder_spec.rb │ ├── hydra_template_spec.rb │ ├── models │ │ ├── control_spec.rb │ │ ├── dataset_spec.rb │ │ ├── result_spec.rb │ │ └── template_spec.rb │ ├── schemas │ │ ├── control_schema_spec.rb │ │ ├── dataset_schema_spec.rb │ │ ├── result_schema_spec.rb │ │ └── template_schema_spec.rb │ ├── service_spec.rb │ └── settings_spec.rb ├── rails_helper.rb ├── routing │ ├── root_routing_spec.rb │ └── subject_routing_spec.rb ├── spec_helper.rb ├── support │ └── shared_examples │ │ ├── backend.rb │ │ └── schema.rb └── vcr_setup.rb └── vendor └── assets ├── javascripts └── .keep └── stylesheets └── .keep /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | !/log/.keep 17 | /tmp 18 | 19 | #Ignore the lock file so we can more easily all have different gems 20 | /Gemfile.lock 21 | 22 | #Ignore Rubymine and jetty files 23 | /.idea 24 | /jetty 25 | /ldf-jetty 26 | 27 | #Ignore yml files 28 | /*.yml 29 | 30 | # Ignore LDF config 31 | config/ldf.yml 32 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | bundler_args: --without debug 3 | script: "bundle exec rake ci" 4 | sudo: false 5 | cache: bundler 6 | rvm: 7 | - 2.3.3 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | 4 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 5 | gem 'rails', '4.2.1' 6 | # Use sqlite3 as the database for Active Record 7 | gem 'sqlite3' 8 | # Use SCSS for stylesheets 9 | gem 'sass-rails', '~> 5.0' 10 | # Use Uglifier as compressor for JavaScript assets 11 | gem 'uglifier', '>= 1.3.0' 12 | # Use CoffeeScript for .coffee assets and views 13 | gem 'coffee-rails', '~> 4.1.0' 14 | # See https://github.com/rails/execjs#readme for more supported runtimes 15 | # gem 'therubyracer', platforms: :ruby 16 | 17 | # Use jquery as the JavaScript library 18 | gem 'jquery-rails' 19 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 20 | gem 'turbolinks' 21 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 22 | gem 'jbuilder', '~> 2.0' 23 | # bundle exec rake doc:rails generates the API under doc/api. 24 | gem 'sdoc', '~> 0.4.0', group: :doc 25 | 26 | # Use ActiveModel has_secure_password 27 | # gem 'bcrypt', '~> 3.1.7' 28 | 29 | # Use Unicorn as the app server 30 | # gem 'unicorn' 31 | 32 | # Use Capistrano for deployment 33 | # gem 'capistrano-rails', group: :development 34 | 35 | gem 'responders' 36 | gem 'rdf' 37 | gem 'rdf-turtle' 38 | gem 'json-ld', '~> 1.99' 39 | #gem 'json-ld' 40 | gem 'active-triples' 41 | #gem 'rdf-vocab', github: "ruby-rdf/rdf-vocab", branch: "develop" 42 | gem 'rdf-vocab', '0.8.7.1' 43 | gem 'jettywrapper', '>= 2.0.0' 44 | gem 'marmotta' 45 | gem 'ldfwrapper', github: 'boston-library/ldf-wrapper', branch: "master" 46 | gem 'rdf-blazegraph' 47 | 48 | group :development, :test do 49 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 50 | gem 'byebug' 51 | 52 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 53 | gem 'spring' 54 | 55 | gem 'rspec-rails' 56 | gem 'pry-byebug' 57 | end 58 | 59 | group :development do 60 | gem 'guard-rspec' 61 | # Access an IRB console on exception pages or by using <%= console %> in views 62 | gem 'web-console', '~> 2.0' 63 | end 64 | 65 | group :test do 66 | gem 'vcr' 67 | gem 'webmock' 68 | end 69 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # A sample Guardfile 2 | # More info at https://github.com/guard/guard#readme 3 | 4 | ## Uncomment and set this to only include directories you want to watch 5 | # directories %w(app lib config test spec features) \ 6 | # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")} 7 | 8 | ## Note: if you are using the `directories` clause above and you are not 9 | ## watching the project directory ('.'), then you will want to move 10 | ## the Guardfile to a watched dir and symlink it back, e.g. 11 | # 12 | # $ mkdir config 13 | # $ mv Guardfile config/ 14 | # $ ln -s config/Guardfile . 15 | # 16 | # and, you'll have to watch "config/Guardfile" instead of "Guardfile" 17 | 18 | # Using -W0 to suppress warnings in automatic test runs 19 | guard :rspec, cmd: 'RUBYOPT="-W0" bundle exec rspec' do 20 | require 'guard/rspec/dsl' 21 | dsl = Guard::RSpec::Dsl.new(self) 22 | 23 | # Feel free to open issues for suggestions and improvements 24 | 25 | # RSpec files 26 | rspec = dsl.rspec 27 | watch(rspec.spec_helper) { rspec.spec_dir } 28 | watch(rspec.spec_support) { rspec.spec_dir } 29 | watch(rspec.spec_files) 30 | 31 | # Ruby files 32 | ruby = dsl.ruby 33 | dsl.watch_spec_files_for(ruby.lib_files) 34 | end 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Linked Data Fragments 2 | ===================== 3 | 4 | A linked data fragment which takes an arbitrary subject and returns a cached 5 | result. 6 | 7 | Configuration 8 | ============= 9 | 10 | YAML 11 | ---- 12 | 13 | You need a ldf.yml file configured. There are currently two sample files for configurations of two different backend 14 | caching layers: ldf.yml.sample_marmotta and ldf.yml.sample_repository. 15 | 16 | Marmotta 17 | -------- 18 | 19 | If you do not already have a marmotta instance, you can use an instance that runs off of jetty by running the following 20 | rake task: 21 | 22 | rake ldfjetty:install 23 | 24 | Once that finishes, please copy config/jetty.yml.sample to config/jetty.yml. You can change the defaults. 25 | 26 | Once that is all setup, here are some commands that can be run to use the marmotta instance: 27 | 28 | rake ldfjetty:stop 29 | rake ldfjetty:config 30 | rake ldfjetty:start 31 | 32 | Blazegraph 33 | ----------- 34 | 35 | If you do not already have a blazegraph instance, you can use an instance that runs off of jetty by running the following 36 | rake task: 37 | 38 | rake ldfjetty:install 39 | 40 | Once that finishes, please copy config/ldfjetty.yml.sample to config/ldfjetty.yml. You can change the defaults. 41 | 42 | It is recommended that you populate Blazegraph with LoC for terms to work. To do this: 43 | 44 | * Download the latest subjects vocab from: [http://id.loc.gov/download/](http://id.loc.gov/download/) (the nt version of “LC Subject Headings (SKOS/RDF only)”) 45 | 46 | * Extract the above download into a directory. 47 | 48 | * Run the following command from that extraction directory: 49 | curl -H 'Content-Type: text/turtle' --upload-file subjects-skos-20140306.nt -X POST "http://localhost:8988/blazegraph/sparql?context-uri=http://id.loc.gov/static/data/authoritiessubjects.nt.skos.zip" 50 | 51 | Once that is all setup, here are some commands that can be run to use the blazegraph instance: 52 | 53 | rake ldfjetty:stop 54 | rake ldfjetty:config 55 | rake ldfjetty:start 56 | 57 | Usage 58 | ===== 59 | 60 | Dataset Response 61 | ---------------- 62 | 63 | In the default config, this is [http://localhost:3000?format=jsonld](http://localhost:3000?format=jsonld) 64 | 65 | Resolving a subject uri 66 | ----------------------- 67 | 68 | In the default config, this would be something like [http://localhost:3000/http://dbpedia.org/resource/Berlin?format=jsonld](http://localhost:3000/http://dbpedia.org/resource/Berlin?format=jsonld) 69 | assuming that you have marmotta running and that linked data source configured in marmotta. 70 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | 8 | desc 'Run CI' 9 | task :ci do 10 | sh 'cp config/ldf.yml.sample_repository config/ldf.yml' 11 | Rake::Task['spec'].invoke 12 | end 13 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require turbolinks 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | 6 | before_action :verify_format 7 | 8 | def verify_format 9 | if !renderer_mapping.keys.include?(request.format.symbol) 10 | raise ActionController::RoutingError.new("Invalid response format specified. Valid response formats are: #{renderer_mapping.keys.join(', ')} (#{renderer_mapping_to_strings.join(', ')}). Example url of how to set format: #{request.base_url}?format=jsonld") 11 | end 12 | end 13 | 14 | 15 | def self.renderer_mapping 16 | { 17 | :nt => lambda { |data| data.dump(:ntriples) }, 18 | :jsonld => lambda { |data| data.dump(:jsonld, :standard_prefixes => true) }, 19 | :ttl => lambda { |data| data.dump(:ttl) } 20 | } 21 | end 22 | 23 | def renderer_mapping 24 | self.class.renderer_mapping 25 | end 26 | 27 | def renderer_mapping_to_strings 28 | result = [] 29 | renderer_mapping.each do |format, renderer| 30 | result.append(Mime::Type.lookup_by_extension(format).to_s) 31 | end 32 | return result 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/dataset_controller.rb: -------------------------------------------------------------------------------- 1 | class DatasetController < ApplicationController 2 | def index 3 | @data = built_dataset 4 | 5 | respond_to do |f| 6 | renderer_mapping.each do |format, renderer| 7 | f.send(format) do 8 | render :text => renderer.call(@data) 9 | end 10 | end 11 | end 12 | end 13 | 14 | private 15 | 16 | def built_dataset 17 | LinkedDataFragments::DatasetBuilder.new.build 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/controllers/subject_controller.rb: -------------------------------------------------------------------------------- 1 | class SubjectController < ApplicationController 2 | before_action :fix_passed_params 3 | 4 | def self.cache_service 5 | LinkedDataFragments::Service.instance.cache 6 | end 7 | 8 | def subject 9 | data = self.class.cache_service.retrieve(params[:subject]) 10 | 11 | respond_to do |f| 12 | renderer_mapping.each do |format, renderer| 13 | f.send(format) do 14 | render :text => renderer.call(data) 15 | end 16 | end 17 | end 18 | end 19 | 20 | private 21 | 22 | # Seems like a double '//' in the captured param is changed to a single one. 23 | # Unsure of how better to do this... 24 | def fix_passed_params 25 | single_slash_match = params[:subject].match(/^http[s]*\:\/(?!\/)/) 26 | 27 | if single_slash_match.present? 28 | params[:subject] = 29 | params[:subject][0..single_slash_match[0].length-1] + '/' + 30 | params[:subject][single_slash_match[0].length..params[:subject].length] 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/app/models/.keep -------------------------------------------------------------------------------- /app/models/setting.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # An alias to LinkedDataFragments::Settings 3 | Setting = LinkedDataFragments::Settings 4 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | LinkedDataFragments 5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | ruby: 3 | version: 2.2.0 4 | dependencies: 5 | post: 6 | - cp config/ldf.yml.sample_repository config/ldf.yml -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module LinkedDataFragments 10 | class Application < Rails::Application 11 | config.autoload_paths += %W(#{config.root}/lib) 12 | # Settings in config/environments/* take precedence over those specified here. 13 | # Application configuration should go into files in config/initializers 14 | # -- all .rb files in that directory are automatically loaded. 15 | 16 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 17 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 18 | # config.time_zone = 'Central Time (US & Canada)' 19 | 20 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 21 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 22 | # config.i18n.default_locale = :de 23 | 24 | # Do not swallow errors in after_commit/after_rollback callbacks. 25 | config.active_record.raise_in_transactional_callbacks = true 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress JavaScripts and CSS. 28 | config.assets.js_compressor = :uglifier 29 | # config.assets.css_compressor = :sass 30 | 31 | # Do not fallback to assets pipeline if a precompiled asset is missed. 32 | config.assets.compile = false 33 | 34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 35 | # yet still be able to expire them through the digest params. 36 | config.assets.digest = true 37 | 38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 39 | 40 | # Specifies the header that your server uses for sending files. 41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | # config.log_tags = [ :subdomain, :uuid ] 53 | 54 | # Use a different logger for distributed setups. 55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 56 | 57 | # Use a different cache store in production. 58 | # config.cache_store = :mem_cache_store 59 | 60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 61 | # config.action_controller.asset_host = 'http://assets.example.com' 62 | 63 | # Ignore bad email addresses and do not raise email delivery errors. 64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 65 | # config.action_mailer.raise_delivery_errors = false 66 | 67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 68 | # the I18n.default_locale when a translation cannot be found). 69 | config.i18n.fallbacks = true 70 | 71 | # Send deprecation notices to registered listeners. 72 | config.active_support.deprecation = :notify 73 | 74 | # Use default logging formatter so that PID and timestamp are not suppressed. 75 | config.log_formatter = ::Logger::Formatter.new 76 | 77 | # Do not dump schema after migrations. 78 | config.active_record.dump_schema_after_migration = false 79 | end 80 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | Mime::Type.register "application/ld+json", :jsonld 6 | Mime::Type.register "application/n-triples", :nt 7 | Mime::Type.register "text/turtle", :ttl 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_linked-data-fragments_session' 4 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/jetty.yml.sample: -------------------------------------------------------------------------------- 1 | development: 2 | startup_wait: 15 3 | jetty_port: 8983 4 | test: &TEST_ 5 | startup_wait: 15 6 | jetty_port: 8983 7 | production: 8 | startup_wait: 15 9 | jetty_port: 8983 -------------------------------------------------------------------------------- /config/ldf.yml.sample_blazegraph: -------------------------------------------------------------------------------- 1 | development: 2 | uri_endpoint: 'http://localhost:3000/{?subject}' 3 | uri_root: 'http://localhost:3000/#dataset' 4 | cache_backend: 5 | provider: 'blazegraph' 6 | url: 'http://localhost:8988/blazegraph/sparql' 7 | context: 'http://localhost:8988/linked_data_fragments_dev' 8 | test: &TEST_ 9 | uri_endpoint: 'http://localhost:3000/{?subject}' 10 | uri_root: 'http://localhost:3000/#dataset' 11 | cache_backend: 12 | provider: 'blazegraph' 13 | url: 'http://localhost:8988/blazegraph/sparql' 14 | context: 'http://localhost:8988/linked_data_fragments_test' 15 | production: 16 | uri_endpoint: 'http://localhost:3000/{?subject}' 17 | uri_root: 'http://localhost:3000/#dataset' 18 | cache_backend: 19 | provider: 'blazegraph' 20 | url: 'http://localhost:8988/blazegraph/sparql' 21 | context: 'http://localhost:8988/linked_data_fragments_production' -------------------------------------------------------------------------------- /config/ldf.yml.sample_marmotta: -------------------------------------------------------------------------------- 1 | development: 2 | uri_endpoint: 'http://localhost:3000/{?subject}' 3 | uri_root: 'http://localhost:3000/#dataset' 4 | cache_backend: 5 | provider: 'marmotta' 6 | url: 'http://localhost:8988/marmotta' 7 | context: 'http://localhost:8988/linked_data_fragments_dev' 8 | test: &TEST_ 9 | uri_endpoint: 'http://localhost:3000/{?subject}' 10 | uri_root: 'http://localhost:3000/#dataset' 11 | cache_backend: 12 | provider: 'marmotta' 13 | url: 'http://localhost:8988/marmotta' 14 | context: 'http://localhost:8988/linked_data_fragments_test' 15 | production: 16 | uri_endpoint: 'http://localhost:3000/{?subject}' 17 | uri_root: 'http://localhost:3000/#dataset' 18 | cache_backend: 19 | provider: 'marmotta' 20 | url: 'http://localhost:8988/marmotta' 21 | context: 'http://localhost:8988/linked_data_fragments_production' -------------------------------------------------------------------------------- /config/ldf.yml.sample_repository: -------------------------------------------------------------------------------- 1 | development: 2 | uri_endpoint: 'http://localhost:3000/{?subject}' 3 | uri_root: 'http://localhost:3000/#dataset' 4 | cache_backend: 5 | provider: 'repository' 6 | test: &TEST_ 7 | uri_endpoint: 'http://localhost:3000/{?subject}' 8 | uri_root: 'http://localhost:3000/#dataset' 9 | cache_backend: 10 | provider: 'repository' 11 | production: 12 | uri_endpoint: 'http://localhost:3000/{?subject}' 13 | uri_root: 'http://localhost:3000/#dataset' 14 | cache_backend: 15 | provider: 'repository' -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root to: "dataset#index" 3 | 4 | get Setting.uri_endpoint_route, to: 'subject#subject', constraints: { 5 | :format => /(#{ApplicationController.renderer_mapping.keys.join("|")})/ 6 | } 7 | end 8 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: 4bef1126e50807c22fd2da7fa2000d9ee794f9126ee0f1ff5d1bc88747730765a5a3421fa1e4949c80a40bfd877b1d249be387300585509782b514ab37f34631 15 | 16 | test: 17 | secret_key_base: 2c06b6eca6cda33a0efe08a55a51ace327133c7f03e496eef569d4416a930ba43e6d9685002737f35684dd7b0196c5cab9c16b88584d3aa2a2f349a77d829d39 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/lib/assets/.keep -------------------------------------------------------------------------------- /lib/linked_data_fragments.rb: -------------------------------------------------------------------------------- 1 | require 'active_triples' 2 | 3 | # must require 'rdf/vocab' first, due to const_missing metaprogramming in 4 | # pre-2.0 verisons 5 | require 'rdf/vocab' 6 | require 'rdf/vocab/hydra' 7 | require 'rdf/vocab/void' 8 | 9 | require 'linked_data_fragments/settings' 10 | 11 | require 'linked_data_fragments/builders' 12 | require 'linked_data_fragments/schemas' 13 | require 'linked_data_fragments/models' 14 | require 'linked_data_fragments/hydra_template' 15 | 16 | ## 17 | # A linked data caching fragment 18 | module LinkedDataFragments 19 | end 20 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/backend_base.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A base class for RDF backends. 4 | # 5 | # Several abstract methods are defined, which implementations must provide 6 | # concrete versions of. 7 | # 8 | # @note this interface provides no method for clearing (deleting) individual 9 | # resources from the cache. 10 | class BackendBase 11 | ## 12 | # A backend factory. 13 | # 14 | # @param name [#to_sym] 15 | # @return [BackendBase] a backend instance 16 | # 17 | # @raise [UnsupportedBackend] when the name does not match a repository 18 | def self.for(name: :repository) 19 | case name.to_sym 20 | when :marmotta 21 | LinkedDataFragments::Marmotta.new 22 | when :repository 23 | LinkedDataFragments::Repository.new 24 | when :blazegraph 25 | LinkedDataFragments::Blazegraph.new 26 | else 27 | raise UnsupportedBackend, "Invalid backend `#{name}` specified." 28 | end 29 | end 30 | 31 | ## 32 | # @!attribute [rw] cache_backend_url 33 | # @return [String, nil] a target url in string form; `nil` may be 34 | # returned when the backend repository is not remote. 35 | # @!attribute [rw] cache_backend_context 36 | # @return [String, nil] the context URI for the cache. When the backend 37 | # supports quads, statements will be stored in this context. `nil` 38 | # selects the default context. 39 | # @see https://www.w3.org/TR/rdf11-concepts/#section-dataset for 40 | # information about named graphs ("contexts") in the RDF abstract syntax 41 | # @see RDF::Dataset for documentation covering named graph support in 42 | # RDF.rb 43 | # @see RDF::Dataset#supports? for details about `:graph_name` support in 44 | # Repositories 45 | attr_accessor :cache_backend_url, :cache_backend_context 46 | 47 | ## 48 | # @abstract Add a resource to the backend. This method retrieves the 49 | # resource from its URI. 50 | # 51 | # @return [void] 52 | # @raise [IOError, Net::HTTPError] when retrieving the resource fails with 53 | # a non-2xx HTTP status code. 54 | # @see RDF::Graph#load this is typical implementation 55 | def add(uri) 56 | raise NotImplementedError, 57 | "#{self.class} should implement `#empty?`, but does not." 58 | end 59 | 60 | ## 61 | # @deprecated Use {#delete_all!} instead. 62 | # @return [void] 63 | def delete_all 64 | warn "[DEPRECATION] `#{self.class}#delete_all` is deprecated; " \ 65 | "use `#{self.class}#delete_all! instead. Called from: " \ 66 | "#{Gem.location_of_caller.join(':')}" 67 | delete_all! 68 | end 69 | 70 | ## 71 | # @abstract Implementations must remove all resources from the backend. 72 | # 73 | # @return [void] 74 | def delete_all! 75 | raise NotImplementedError, 76 | "#{self.class} should implement `#delete_all!`, but does not." 77 | end 78 | 79 | ## 80 | # @abstract 81 | # @return [Boolean] `true` if no resources are stored. 82 | def empty? 83 | raise NotImplementedError, 84 | "#{self.class} should implement `#empty?`, but does not." 85 | end 86 | 87 | ## 88 | # @deprecation This now just echos the argument. Callers should remove 89 | # sends to this method, and use the argument instead. 90 | # @param uri [String, RDF::URI] a URI or URI-like string 91 | # @return [String, RDF::URI] the mapped string 92 | def get_resource_uri(uri) 93 | warn '[DEPRECATION] #get_resource_uri echos its argument. Callers ' \ 94 | 'should replace method calls with the argument, instead ' \ 95 | "Called from: #{Gem.location_of_caller.join(':')}" 96 | uri 97 | end 98 | 99 | ## 100 | # @abstract checks whether the resource is in the cache 101 | # 102 | # @param uri [String, RDF::URI] a URI or URI-like string 103 | # @return [Boolean] 104 | def has_resource?(uri) 105 | raise NotImplementedError, 106 | "#{self.class} should implement `#has_resource?`, but does not." 107 | end 108 | 109 | ## 110 | # @abstract Retrieves RDF statements for a selected resource. 111 | # 112 | # @todo Should this simply implement the base verison against 113 | # `RDF::Repository`? 114 | # @todo What are we supposed to return if the resource does not exist? 115 | # 116 | # @param uri [String, RDF::URI] a URI or URI-like string 117 | # @return [RDF::Enumerable] the statements representing requested resource 118 | def retrieve(uri) 119 | raise NotImplementedError, 120 | "#{self.class} should implement `#retrieve!`, but does not." 121 | end 122 | 123 | class UnsupportedBackend < NameError; end 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/blazegraph.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class Blazegraph < BackendBase 3 | def initialize 4 | #@repo ||= ::RDF::Blazegraph::Repository.new(uri: Setting.cache_backend_url, context: Setting.cache_backend_context) 5 | self.cache_backend_url = Setting.cache_backend_url 6 | self.cache_backend_context = Setting.cache_backend_context 7 | @repo ||= ::RDF::Blazegraph::Repository.new(Setting.cache_backend_url) 8 | end 9 | 10 | def retrieve(uri) 11 | @repo.load(uri) unless @repo.has_subject?(RDF::URI.new(uri)) 12 | 13 | @repo.query(:subject => RDF::URI.new(uri)) 14 | end 15 | 16 | def delete_all 17 | @repo.clear 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/builders.rb: -------------------------------------------------------------------------------- 1 | require 'linked_data_fragments/builders/control_builder' 2 | require 'linked_data_fragments/builders/dataset_builder' 3 | require 'linked_data_fragments/builders/template_builder' 4 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/builders/control_builder.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class ControlBuilder 3 | ## 4 | # @!attribute [rw] control 5 | # @return [] 6 | # @!attribute [rw] property 7 | # @return [RDF::URI] 8 | attr_accessor :control, :property 9 | 10 | ## 11 | # 12 | def initialize(control, property) 13 | @control = control 14 | @property = property 15 | end 16 | 17 | ## 18 | # @return [Control] 19 | def build 20 | Control.new.tap do |t| 21 | t.variable = control 22 | t.property = property 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/builders/dataset_builder.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A Builder for Dataset instances. 4 | # 5 | # @example Building a dataset 6 | # builder = DatasetBuilder.new 7 | # builder.uri_endpoint = HydraTemplate.new('http://example.com/{?subject}') 8 | # dataset = builder.build 9 | # 10 | # dataset.dump :ttl 11 | # # a , 12 | # # ; 13 | # # "http://example.com/{?subject}"; 14 | # # [ 15 | # # [ 16 | # # ; 17 | # # "subject" 18 | # # ]; 19 | # # "http://example.com/{?subject}" 20 | # # ] . 21 | class DatasetBuilder 22 | ## 23 | # @!attribute [r] control_mapping 24 | # @return [Control] 25 | # @!attribute [r] uri_root 26 | # @return [String] a URI-like string representing the root URI for the 27 | # dataset. 28 | # @see Settings#uri_root 29 | # @!attribute [rw] uri_endpoint 30 | # @return [HydraTemplate] 31 | attr_reader :control_mapping, :uri_endpoint, :uri_root 32 | 33 | ## 34 | # @param control_mapping [Control] 35 | # @param uri_endpoint [HydraTemplate] 36 | # @param uri_root [String] a URI-like string representing the root URI 37 | # for the dataset. 38 | def initialize(control_mapping: { 'subject' => RDF.subject }, 39 | uri_endpoint: default_template, 40 | uri_root: Settings.uri_root) 41 | @control_mapping = control_mapping 42 | @uri_endpoint = uri_endpoint 43 | @uri_root = uri_root 44 | end 45 | 46 | ## 47 | # @return [Dataset] the dataset built from the current builder state 48 | def build 49 | Dataset.new(uri_root).tap do |dataset| 50 | dataset.uri_lookup_endpoint = uri_endpoint.to_s 51 | dataset.search = template_builder.new(dataset, uri_endpoint).build 52 | 53 | uri_endpoint.controls.each do |control| 54 | dataset.search.first.mapping << 55 | control_builder.new(control, control_mapping[control]).build 56 | end 57 | end 58 | end 59 | 60 | private 61 | 62 | def control_builder 63 | ControlBuilder 64 | end 65 | 66 | def template_builder 67 | TemplateBuilder 68 | end 69 | 70 | def default_template 71 | LinkedDataFragments::HydraTemplate.new(Settings.uri_endpoint) 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/builders/template_builder.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A Builder for Templates. 4 | class TemplateBuilder 5 | ## 6 | # @!attribute [r] dataset_node 7 | # @return [Dataset] 8 | # @!attribute [r] uri_template 9 | # @return [String] 10 | attr_reader :dataset_node, :uri_template 11 | 12 | ## 13 | # @param dataset_node [Dataset] 14 | # @param uri_template [#to_s] 15 | def initialize(dataset_node, uri_template) 16 | @dataset_node = dataset_node 17 | @uri_template = uri_template.to_s 18 | end 19 | 20 | def build 21 | Template.new(nil, dataset_node).tap do |template| 22 | template.template = self.uri_template 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/hydra_template.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class HydraTemplate 3 | CONTROL_REGEX = /{\??(.*?)}/.freeze 4 | 5 | ## 6 | # @!attribute [r] template 7 | # @return [String] 8 | attr_reader :template 9 | 10 | ## 11 | # @param template [#to_s] 12 | def initialize(template) 13 | @template = template.to_s 14 | end 15 | 16 | ## 17 | # @return [Array] Array of controls in template. 18 | def controls 19 | @controls ||= template.scan(CONTROL_REGEX) 20 | .flatten # Reduce multiple matches 21 | .flat_map{|x| x.split(",")} # Split on commas for matches 22 | .map(&:strip) # Strip whitespace 23 | end 24 | 25 | ## 26 | # @return [String] the template 27 | def to_s 28 | @template.to_s 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/marmotta.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class Marmotta < BackendBase 3 | 4 | def initialize 5 | self.cache_backend_url = Setting.cache_backend_url 6 | self.cache_backend_context = Setting.cache_backend_context 7 | @connection = ::Marmotta::Connection.new(uri: Setting.cache_backend_url, context: Setting.cache_backend_context) 8 | end 9 | 10 | def retrieve(uri) 11 | resource = ::Marmotta::Resource.new(uri, connection: @connection) 12 | resulting_graph = resource.get 13 | 14 | return resulting_graph 15 | end 16 | 17 | def delete_all 18 | @connection.delete_all 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/models.rb: -------------------------------------------------------------------------------- 1 | require 'linked_data_fragments/models/control' 2 | require 'linked_data_fragments/models/dataset' 3 | require 'linked_data_fragments/models/result' 4 | require 'linked_data_fragments/models/template' 5 | 6 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/models/control.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class Control 3 | include ActiveTriples::RDFSource 4 | apply_schema LinkedDataFragments::ControlSchema 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/models/dataset.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # An RDFSource of type `hydracore:Collection`. Implements the metadata schema 4 | # of `DatasetSchema`. 5 | class Dataset 6 | include ActiveTriples::RDFSource 7 | 8 | configure :type => [ 9 | RDF::URI.intern("http://www.w3.org/ns/hydra/core#Collection"), 10 | RDF::Vocab::VOID.Dataset 11 | ] 12 | 13 | apply_schema LinkedDataFragments::DatasetSchema 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/models/result.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class Result 3 | include ActiveTriples::RDFSource 4 | configure :type => [ 5 | RDF::URI("http://www.w3.org/ns/hydra/core#Collection"), 6 | RDF::URI("http://www.w3.org/ns/hydra/core#PagedCollection") 7 | ] 8 | 9 | apply_schema LinkedDataFragments::ResultSchema 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/models/template.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | class Template 3 | include ActiveTriples::RDFSource 4 | 5 | apply_schema LinkedDataFragments::TemplateSchema 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/repository.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A basic `RDF::Repository` backend. This simply wraps RDF::Repository with 4 | # the smaller `BackendBase` interface. 5 | # 6 | 7 | # @example with a new in-memory repository 8 | # backend = LinkedDataFragments.new 9 | # backend.retrieve('http://example.com/moomin') 10 | # 11 | # @example with an existing repository instance 12 | # my_repository = RDF::Repository.new 13 | # backend = LinkedDataFragments.new(repository: my_repository) 14 | # backend.retrieve('http://example.com/moomin') 15 | # 16 | class Repository < BackendBase 17 | ## 18 | # @param repository [RDF::Repository] a repository instance 19 | def initialize(repository: RDF::Repository.new) 20 | @repo = repository 21 | end 22 | 23 | ## 24 | # @see BackendBase#add 25 | def add(uri) 26 | @repo.load(uri) 27 | end 28 | 29 | ## 30 | # Removes all resources from the backend. 31 | # 32 | # @return [void] 33 | def delete_all! 34 | @repo.clear 35 | end 36 | 37 | ## 38 | # @see BackendBase#empty? 39 | def empty? 40 | @repo.empty? 41 | end 42 | 43 | ## 44 | # @see BackendBase#has_resource? 45 | def has_resource?(uri) 46 | @repo.has_subject?(RDF::URI.new(uri)) 47 | end 48 | 49 | ## 50 | # @see BackendBase#retrieve 51 | def retrieve(uri) 52 | @repo.load(uri) unless has_resource?(uri) 53 | 54 | resulting_graph = @repo.query(:subject => RDF::URI.new(uri)) 55 | return resulting_graph 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/schemas.rb: -------------------------------------------------------------------------------- 1 | require 'linked_data_fragments/schemas/control_schema' 2 | require 'linked_data_fragments/schemas/dataset_schema' 3 | require 'linked_data_fragments/schemas/result_schema' 4 | require 'linked_data_fragments/schemas/template_schema' 5 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/schemas/control_schema.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A HydraCore control schema 4 | class ControlSchema < ActiveTriples::Schema 5 | property :variable, :predicate => RDF::Vocab::HYDRA.variable 6 | property :property, :predicate => RDF::Vocab::HYDRA.property, :cast => false 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/schemas/dataset_schema.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A schema for `hydracore:Collection`/`Dataset` nodes. 4 | class DatasetSchema < ActiveTriples::Schema 5 | property :subset, predicate: RDF::Vocab::VOID.subset 6 | property :uri_lookup_endpoint, predicate: RDF::Vocab::VOID.uriLookupEndpoint 7 | 8 | # Change search so that it points to a search node. 9 | property :search, predicate: RDF::URI.intern("http://www.w3.org/ns/hydra/core#search") 10 | property :member, predicate: RDF::URI.intern("http://www.w3.org/ns/hydra/core#member") 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/schemas/result_schema.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # Schema for Result model 4 | class ResultSchema < ActiveTriples::Schema 5 | property :subset, :predicate => RDF::Vocab::VOID.subset 6 | 7 | # Descriptive 8 | property :title, :predicate => RDF::Vocab::DC.title 9 | property :description, :predicate => RDF::Vocab::DC.description 10 | property :source, :predicate => RDF::Vocab::DC.source 11 | 12 | # Pagination 13 | property :triples_count, :predicate => RDF::Vocab::VOID.triples 14 | property :total_items, :predicate => RDF::URI("http://www.w3.org/ns/hydra/core#totalItems") 15 | property :items_per_page, :predicate => RDF::URI("http://www.w3.org/ns/hydra/core#itemsPerPage") 16 | property :first_page, :predicate => RDF::URI("http://www.w3.org/ns/hydra/core#firstPage") 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/schemas/template_schema.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # Schema for template models 4 | class TemplateSchema < ActiveTriples::Schema 5 | property :template, :predicate => RDF::Vocab::HYDRA.search 6 | property :mapping, :predicate => RDF::Vocab::HYDRA.mapping 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/service.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # The cache 4 | class Service 5 | include Singleton 6 | 7 | ## 8 | # @return [BackendBase] 9 | # @raise [BackendBase::UnsupportedBackend] when the configured repository is 10 | # not supported 11 | def cache 12 | @cache ||= BackendBase.for(name: Settings.cache_backend) 13 | rescue BackendBase::UnsupportedBackend 14 | raise BackendBase::UnsupportedBackend, 'Invalid cache_backend set in the yml config' 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/linked_data_fragments/settings.rb: -------------------------------------------------------------------------------- 1 | module LinkedDataFragments 2 | ## 3 | # A class to hold site-wide configuration. 4 | # 5 | # @todo Extract to a configuration file. 6 | class Settings 7 | class << self 8 | ## 9 | # @return [String] 10 | def app_root 11 | return @app_root if @app_root 12 | @app_root = Rails.root if defined?(Rails) and defined?(Rails.root) 13 | @app_root ||= APP_ROOT if defined?(APP_ROOT) 14 | @app_root ||= '.' 15 | end 16 | 17 | ## 18 | # @return [Hash] the settings from the YAML config 19 | # at {.config_path}. 20 | def config 21 | @config ||= YAML::load(File.open(config_path)) 22 | .fetch(env) { raise "#{env} missing from ldf.yml" } 23 | .with_indifferent_access 24 | end 25 | 26 | ## 27 | # @return [String] 28 | def config_path 29 | File.join(app_root, 'config', 'ldf.yml') 30 | end 31 | 32 | ## 33 | # @return [String] 34 | def env 35 | return @env if @env 36 | #The following commented line always returns "test" in a rails c production console. Unsure of how to fix this yet... 37 | #@env = ENV["RAILS_ENV"] = "test" if ENV 38 | @env ||= Rails.env if defined?(Rails) and defined?(Rails.root) 39 | @env ||= 'development' 40 | end 41 | 42 | ## 43 | # @return [String] 44 | def uri_endpoint 45 | config[:uri_endpoint] || 'http://localhost:3000/{?subject}' 46 | end 47 | 48 | def uri_endpoint_route 49 | if uri_endpoint.match(/^http[s]*\:\/\/.+\//) 50 | endpoint = uri_endpoint.gsub(/^http[s]*\:\/\/[^\/]+/, '') 51 | endpoint.gsub!('{?subject}', '*subject') 52 | else 53 | #FIXME: What type of error should this be? Need to unit test this as well once figured out. 54 | raise ArgumentError, 'Invalid uri endpoint url specified' 55 | end 56 | 57 | endpoint 58 | end 59 | 60 | def uri_root 61 | config[:uri_root] || 'http://localhost:3000/#dataset' 62 | end 63 | 64 | def cache_backend 65 | config[:cache_backend][:provider] || 'marmotta' 66 | end 67 | 68 | def cache_backend_url 69 | config[:cache_backend][:url] || 'http://localhost:8988/marmotta' 70 | end 71 | 72 | def cache_backend_context 73 | config[:cache_backend][:context] || 'linked_data_fragments_unknown' 74 | end 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/lib/tasks/.keep -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/log/.keep -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /spec/caching/blazegraph_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe LinkedDataFragments::Blazegraph do 4 | subject { 5 | allow(Setting).to receive(:cache_backend).and_return('blazegraph') 6 | allow(Setting).to receive(:cache_backend_url).and_return('http://localhost:8988/blazegraph/sparql') 7 | allow(Setting).to receive(:cache_backend_context).and_return('http://localhost:8988/linked-data-fragments-test') 8 | LinkedDataFragments::Blazegraph.new 9 | } 10 | 11 | after do 12 | subject.delete_all 13 | end 14 | 15 | context "retrieve a subject uri", :vcr do 16 | it "should be configured as a Blazegraph instance with the mocked uri" do 17 | expect(subject).to be_instance_of LinkedDataFragments::Blazegraph 18 | expect(subject.cache_backend_url).to eq "http://localhost:8988/blazegraph/sparql" 19 | expect(subject.cache_backend_context).to eq "http://localhost:8988/linked-data-fragments-test" 20 | end 21 | 22 | it "should retrieve and return a response on a valid subject uri" do 23 | expect(subject.retrieve('http://dbpedia.org/resource/Berlin').dump(:ttl)).to match /http\:\/\/dbpedia.org\/resource\/Category\:Berlin/ 24 | end 25 | 26 | xit "should retrieve nothing on an invalid uri" do 27 | expect(subject.retrieve('http://dbpedia.org/resource/BerlinInvalidAndNotReal')).to be_empty 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/caching/marmotta_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe LinkedDataFragments::Marmotta do 4 | subject { 5 | allow(Setting).to receive(:cache_backend).and_return('marmotta') 6 | allow(Setting).to receive(:cache_backend_url).and_return('http://localhost:8988/marmotta') 7 | allow(Setting).to receive(:cache_backend_context).and_return('http://localhost:8988/linked-data-fragments-test') 8 | LinkedDataFragments::Marmotta.new 9 | } 10 | 11 | after do 12 | subject.delete_all 13 | end 14 | 15 | context "retrieve a subject uri", :vcr do 16 | it "should be configured as a Marmotta instance with the mocked uri" do 17 | expect(subject).to be_instance_of LinkedDataFragments::Marmotta 18 | expect(subject.cache_backend_url).to eq "http://localhost:8988/marmotta" 19 | expect(subject.cache_backend_context).to eq "http://localhost:8988/linked-data-fragments-test" 20 | end 21 | it "should retrieve and return a response on a valid subject uri" do 22 | expect(subject.retrieve('http://dbpedia.org/resource/Berlin').dump(:ttl)).to match /http\:\/\/dbpedia.org\/resource\/Category\:Berlin/ 23 | end 24 | 25 | it "should retrieve nothing on an invalid uri" do 26 | expect(subject.retrieve('http://dbpedia.org/resource/BerlinInvalidAndNotReal')).to be_empty 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/caching/repository_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe LinkedDataFragments::Repository do 4 | subject { 5 | allow(Setting).to receive(:cache_backend).and_return(:repository) 6 | LinkedDataFragments::Repository.new 7 | } 8 | 9 | after { subject.delete_all! } 10 | 11 | it_behaves_like 'a backend' 12 | 13 | context "retrieve a subject uri", :vcr do 14 | it "should be configured as a Repository instance" do 15 | expect(subject).to be_instance_of LinkedDataFragments::Repository 16 | end 17 | 18 | it "should retrieve and return a response on a valid subject uri" do 19 | expect(subject.retrieve('http://dbpedia.org/resource/Berlin').dump(:ttl)).to match /http\:\/\/dbpedia.org\/resource\/Category\:Berlin/ 20 | end 21 | 22 | it "should retrieve nothing on an invalid uri" do 23 | expect(subject.retrieve('http://dbpedia.org/resource/BerlinInvalidAndNotReal')).to be_empty 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/cassettes/LinkedDataFragments_Blazegraph/retrieve_a_subject_uri/should_be_configured_as_a_Blazegraph_instance_with_the_mocked_uri.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: delete 5 | uri: http://localhost:8988/blazegraph/sparql 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Accept-Encoding: 11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 12 | Accept: 13 | - "*/*" 14 | User-Agent: 15 | - Ruby 16 | Host: 17 | - localhost:8988 18 | Connection: 19 | - keep-alive 20 | Keep-Alive: 21 | - 30 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Content-Type: 28 | - application/xml;charset=ISO-8859-1 29 | Content-Length: 30 | - '59' 31 | body: 32 | encoding: UTF-8 33 | string: 34 | http_version: 35 | recorded_at: Sat, 04 Feb 2017 04:22:07 GMT 36 | recorded_with: VCR 3.0.3 37 | -------------------------------------------------------------------------------- /spec/cassettes/LinkedDataFragments_Marmotta/retrieve_a_subject_uri/should_be_configured_as_a_Marmotta_instance_with_the_mocked_uri.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: delete 5 | uri: http://localhost:8988/marmotta/context/http://localhost:8988/linked-data-fragments-test 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Hurley v0.2 12 | Accept: 13 | - application/ld+json 14 | Content-Type: 15 | - application/ld+json 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | response: 19 | status: 20 | code: 200 21 | message: OK 22 | headers: 23 | Content-Length: 24 | - '0' 25 | body: 26 | encoding: UTF-8 27 | string: '' 28 | http_version: 29 | recorded_at: Sat, 04 Feb 2017 04:22:13 GMT 30 | recorded_with: VCR 3.0.3 31 | -------------------------------------------------------------------------------- /spec/cassettes/LinkedDataFragments_Marmotta/retrieve_a_subject_uri/should_retrieve_and_return_a_response_on_a_valid_subject_uri.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://localhost:8988/marmotta/resource?uri=http://dbpedia.org/resource/Berlin 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Hurley v0.2 12 | Accept: 13 | - application/ld+json 14 | Content-Type: 15 | - application/ld+json 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | response: 19 | status: 20 | code: 303 21 | message: See Other 22 | headers: 23 | Content-Type: 24 | - application/ld+json; q=1.0; rel=meta 25 | Etag: 26 | - W/"959e57d0" 27 | Last-Modified: 28 | - Sat, 04 Feb 2017 03:04:25 GMT 29 | Location: 30 | - http://localhost:8988/marmotta/meta/application/ld+json?uri=http%3A%2F%2Fdbpedia.org%2Fresource%2FBerlin 31 | Vary: 32 | - Accept 33 | Content-Length: 34 | - '0' 35 | body: 36 | encoding: UTF-8 37 | string: '' 38 | http_version: 39 | recorded_at: Sat, 04 Feb 2017 04:22:13 GMT 40 | - request: 41 | method: get 42 | uri: http://localhost:8988/marmotta/meta/application/ld+json?uri=http://dbpedia.org/resource/Berlin 43 | body: 44 | encoding: US-ASCII 45 | string: '' 46 | headers: 47 | User-Agent: 48 | - Hurley v0.2 49 | Accept: 50 | - application/ld+json 51 | Content-Type: 52 | - application/ld+json 53 | Accept-Encoding: 54 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 55 | response: 56 | status: 57 | code: 200 58 | message: OK 59 | headers: 60 | Link: 61 | - ; 62 | rel="timegate",; 63 | rel="timemap" 64 | Content-Disposition: 65 | - attachment; filename="Berlin.jsonld" 66 | Content-Type: 67 | - application/ld+json; charset=utf-8 68 | Etag: 69 | - W/"959e57d0" 70 | Last-Modified: 71 | - Sat, 04 Feb 2017 03:04:25 GMT 72 | Transfer-Encoding: 73 | - chunked 74 | body: 75 | encoding: ASCII-8BIT 76 | string: !binary |- 77 | WyB7CiAgIkBncmFwaCIgOiBbIHsKICAgICJAaWQiIDogImh0dHA6Ly9kYnBl 78 | ZGlhLm9yZy9yZXNvdXJjZS9CZXJsaW4iLAogICAgIkB0eXBlIiA6IFsgImh0 79 | dHA6Ly9kYnBlZGlhLm9yZy9jbGFzcy95YWdvL0FkbWluaXN0cmF0aXZlRGlz 80 | dHJpY3QxMDg0OTE4MjYiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lh 81 | Z28vQXJlYTEwODQ5NzI5NCIsICJodHRwOi8vZGJwZWRpYS5vcmcvY2xhc3Mv 82 | eWFnby9DYXBpdGFsMTA4NTE4NTA1IiwgImh0dHA6Ly9kYnBlZGlhLm9yZy9j 83 | bGFzcy95YWdvL0NlbnRlcjEwODUyMzQ4MyIsICJodHRwOi8vZGJwZWRpYS5v 84 | cmcvY2xhc3MveWFnby9DaXR5MTA4NTI0NzM1IiwgImh0dHA6Ly9kYnBlZGlh 85 | Lm9yZy9jbGFzcy95YWdvL0Rpc3RyaWN0MTA4NTUyMTM4IiwgImh0dHA6Ly9k 86 | YnBlZGlhLm9yZy9jbGFzcy95YWdvL0dlb2dyYXBoaWNhbEFyZWExMDg1NzQz 87 | MTQiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vTG9jYXRpb24x 88 | MDAwMjcxNjciLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vTXVu 89 | aWNpcGFsaXR5MTA4NjI2MjgzIiwgImh0dHA6Ly9kYnBlZGlhLm9yZy9jbGFz 90 | cy95YWdvL09iamVjdDEwMDAwMjY4NCIsICJodHRwOi8vZGJwZWRpYS5vcmcv 91 | Y2xhc3MveWFnby9QaHlzaWNhbEVudGl0eTEwMDAwMTkzMCIsICJodHRwOi8v 92 | ZGJwZWRpYS5vcmcvY2xhc3MveWFnby9SZWdpb24xMDg2MzA5ODUiLCAiaHR0 93 | cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vU2VhdDEwODY0Nzk0NSIsICJo 94 | dHRwOi8vZGJwZWRpYS5vcmcvY2xhc3MveWFnby9TZWN0aW9uMTA4NjQ4MzIy 95 | IiwgImh0dHA6Ly9kYnBlZGlhLm9yZy9jbGFzcy95YWdvL1NpdGUxMDg2NTEy 96 | NDciLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vU3RhdGVDYXBp 97 | dGFsMTA4Njk1NTM5IiwgImh0dHA6Ly9kYnBlZGlhLm9yZy9jbGFzcy95YWdv 98 | L1Rvd24xMDg2NjU1MDQiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lh 99 | Z28vVHJhY3QxMDg2NzMzOTUiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNz 100 | L3lhZ28vVXJiYW5BcmVhMTA4Njc1OTY3IiwgImh0dHA6Ly9kYnBlZGlhLm9y 101 | Zy9jbGFzcy95YWdvL1ZpY2luaXR5MTA4NjQxMTEzIiwgImh0dHA6Ly9kYnBl 102 | ZGlhLm9yZy9jbGFzcy95YWdvL1dpa2ljYXRDYXBpdGFsc0luRXVyb3BlIiwg 103 | Imh0dHA6Ly9kYnBlZGlhLm9yZy9jbGFzcy95YWdvL1dpa2ljYXRDaXRpZXNJ 104 | bkdlcm1hbnkiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vV2lr 105 | aWNhdENpdGllc1dpdGhNaWxsaW9uc09mSW5oYWJpdGFudHMiLCAiaHR0cDov 106 | L2RicGVkaWEub3JnL2NsYXNzL3lhZ28vV2lraWNhdEdlcm1hblN0YXRlQ2Fw 107 | aXRhbHMiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vV2lraWNh 108 | dExvY2FsaXRpZXNPZkJlcmxpbiIsICJodHRwOi8vZGJwZWRpYS5vcmcvY2xh 109 | c3MveWFnby9XaWtpY2F0TXVuaWNpcGFsaXRpZXNPZkdlcm1hbnkiLCAiaHR0 110 | cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vV2lraWNhdFBvcHVsYXRlZFBs 111 | YWNlc0VzdGFibGlzaGVkSW5UaGUxM3RoQ2VudHVyeSIsICJodHRwOi8vZGJw 112 | ZWRpYS5vcmcvY2xhc3MveWFnby9XaWtpY2F0U3RhdGVzQW5kVGVycml0b3Jp 113 | ZXNFc3RhYmxpc2hlZEluMTIzNyIsICJodHRwOi8vZGJwZWRpYS5vcmcvY2xh 114 | c3MveWFnby9XaWtpY2F0U3RhdGVzT2ZHZXJtYW55IiwgImh0dHA6Ly9kYnBl 115 | ZGlhLm9yZy9jbGFzcy95YWdvL1dpa2ljYXRVbml2ZXJzaXR5VG93bnNJbkdl 116 | cm1hbnkiLCAiaHR0cDovL2RicGVkaWEub3JnL2NsYXNzL3lhZ28vV2lraWNh 117 | dFdvcmxkSGVyaXRhZ2VTaXRlc0luR2VybWFueSIsICJodHRwOi8vZGJwZWRp 118 | YS5vcmcvY2xhc3MveWFnby9ZYWdvR2VvRW50aXR5IiwgImh0dHA6Ly9kYnBl 119 | ZGlhLm9yZy9jbGFzcy95YWdvL1lhZ29MZWdhbEFjdG9yR2VvIiwgImh0dHA6 120 | Ly9kYnBlZGlhLm9yZy9jbGFzcy95YWdvL1lhZ29QZXJtYW5lbnRseUxvY2F0 121 | ZWRFbnRpdHkiLCAiaHR0cDovL2RicGVkaWEub3JnL29udG9sb2d5LyUzQ2h0 122 | dHA6Ly9wdXJsLm9yZy9kYy90ZXJtcy9KdXJpc2RpY3Rpb24lM0UiLCAiaHR0 123 | cDovL2RicGVkaWEub3JnL29udG9sb2d5L0FkbWluaXN0cmF0aXZlUmVnaW9u 124 | IiwgImh0dHA6Ly9kYnBlZGlhLm9yZy9vbnRvbG9neS9Mb2NhdGlvbiIsICJo 125 | dHRwOi8vZGJwZWRpYS5vcmcvb250b2xvZ3kvUGxhY2UiLCAiaHR0cDovL2Ri 126 | cGVkaWEub3JnL29udG9sb2d5L1BvcHVsYXRlZFBsYWNlIiwgImh0dHA6Ly9k 127 | YnBlZGlhLm9yZy9vbnRvbG9neS9SZWdpb24iLCAiaHR0cDovL3NjaGVtYS5v 128 | cmcvQWRtaW5pc3RyYXRpdmVBcmVhIiwgImh0dHA6Ly9zY2hlbWEub3JnL1Bs 129 | YWNlIiwgImh0dHA6Ly91bWJlbC5vcmcvdW1iZWwvcmMvQ2l0eSIsICJodHRw 130 | Oi8vdW1iZWwub3JnL3VtYmVsL3JjL0xvY2F0aW9uX1VuZGVyc3BlY2lmaWVk 131 | IiwgImh0dHA6Ly91bWJlbC5vcmcvdW1iZWwvcmMvUG9wdWxhdGVkUGxhY2Ui 132 | LCAiaHR0cDovL3VtYmVsLm9yZy91bWJlbC9yYy9WaWxsYWdlIiwgImh0dHA6 133 | Ly93d3cudzMub3JnLzIwMDIvMDcvb3dsI1RoaW5nIiwgImh0dHA6Ly93d3cu 134 | dzMub3JnLzIwMDMvMDEvZ2VvL3dnczg0X3BvcyNTcGF0aWFsVGhpbmciLCAi 135 | aHR0cDovL3d3dy53aWtpZGF0YS5vcmcvZW50aXR5L1EzNDU1NTI0IiwgImh0 136 | dHA6Ly93d3cud2lraWRhdGEub3JnL2VudGl0eS9RNDg2OTcyIiBdLAogICAg 137 | Imh0dHA6Ly9kYnBlZGlhLm9yZy9vbnRvbG9neS9Qb3B1bGF0ZWRQbGFjZS9h 138 | cmVhVG90YWwiIDogWyB7CiAgICAgICJAdHlwZSIgOiAiaHR0cDovL2RicGVk 139 | aWEub3JnL2RhdGF0eXBlL3NxdWFyZUtpbG9tZXRyZSIsCiAgICAgICJAdmFs 140 | dWUiIDogIjg5MS44NSIKICAgIH0gXSwKICAgICJodHRwOi8vZGJwZWRpYS5v 141 | cmcvb250b2xvZ3kvYWJzdHJhY3QiIDogWyB7CiAgICAgICJAbGFuZ3VhZ2Ui 142 | IDogImFyIiwKICAgICAgIkB2YWx1ZSIgOiAi2KjYsdmE2YrZhiAo2KPZhNmF 143 | 2KfZhtmK2Kk6IEJlcmxpbikg2YfZiiDYudin2LXZhdipINis2YXZh9mI2LHZ 144 | itipINij2YTZhdin2YbZitinINin2YTYp9iq2K3Yp9iv2YrYqdiMINmI2KXY 145 | rdiv2Ykg2YjZhNin2YrYp9iqINij2YTZhdin2YbZitinINin2YTYs9iqINi5 146 | 2LTYsdip2Iwg2YPZhdinINij2YbZh9inINij2YPYqNixINmF2K/ZhiDYo9mE 147 | 2YXYp9mG2YrYpyDZhdmGINit2YrYqyDYudiv2K8g2KfZhNiz2YPYp9mGLiDZ 148 | iNiq2LnYqtio2LEg2KjYsdmE2YrZhiDYpdit2K/ZiSBcItin2YTZiNmE2KfZ 149 | itin2Kog2KfZhNmF2K/ZhlwiINin2YTYq9mE2KfYqyDYqNis2YXZh9mI2LHZ 150 | itipINij2YTZhdin2YbZitinINin2YTYp9iq2K3Yp9iv2YrYqSAo2KXZhNmJ 151 | INis2KfZhtioINio2LHZitmF2YYg2YjZh9in2YXYqNmI2LHYuinYjCDZiNiq 152 | 2KPYqtmKINmH2LDZhyDYp9mE2KrYs9mF2YrYqSDZhdmGINmD2YjZhiDYrdiv 153 | 2YjYryDYp9mE2YXYr9mK2YbYqSDZh9mKINmG2YHYs9mH2Kcg2K3Yr9mI2K8g 154 | 2KfZhNmI2YTYp9mK2KkuINmI2KjYsdmE2YrZhiDZh9mKINij2YrYttin2Ysg 155 | 2KvYp9mG2Yog2KPZg9io2LEg2YXYr9mGINin2YTYp9iq2K3Yp9ivINin2YTY 156 | o9mI2LHZiNio2Yog2KjYudivINin2YTYudin2LXZhdipINin2YTYqNix2YrY 157 | t9in2YbZitipINmE2YbYr9mGLtmI2K7ZhNin2YQg2YHYqtix2KnYp9mE2K3Y 158 | sdioINin2YTYqNin2LHYr9ipINmI2KrYrdiv2YrYr9in2Ysg2YHZiiDYudin 159 | 2YUgMTk2MdiMINmC2KfZhdiqINit2YPZiNmF2Kkg2KPZhNmF2KfZhtmK2Kcg 160 | 2KfZhNi02LHZgtmK2Kkg2KjYqti02YrZitivINmF2Kcg2YPYp9mGINmK2LnY 161 | sdmBINio2YDYrNiv2KfYsSDYqNix2YTZitmGLiDZh9mD2LDYpyDYo9i12KjY 162 | rdiqINio2LHZhNmK2YYg2YXYr9mK2YbYqSDZhdmP2YLYs9mF2Kkg2KXZhNmJ 163 | INis2LLYptmK2YY6INis2LLYoSDYutix2KjZiiDZitiq2KjYuSDYo9mE2YXY 164 | p9mG2YrYpyDYp9mE2LrYsdio2YrYqSDZiNin2YTYotiu2LEg2LTYsdmC2Yog 165 | 2YrYqtio2Lkg2KPZhNmF2KfZhtmK2Kcg2KfZhNi02LHZgtmK2KkuINmI2KjZ 166 | gtmKINin2YTYrdin2YQg2YHZiiDYqNix2YTZitmGINi52YTZiSDZh9iw2Kcg 167 | 2KfZhNmG2K3ZiCDYpdmE2Ykg2K3ZitmGINiz2YLZiNi3INin2YTYrNiv2KfY 168 | sSDZgdmKINi52KfZhSAxOTg5INmI2KrZiNit2YrYryDYp9mE2KPZhNmF2KfZ 169 | htmK2KrZitmGINmB2Yog2LnYp9mFIDE5OTDYjCDZiNin2K7YqtmK2LHYqiDY 170 | qNix2YTZitmGINio2LnYr9mH2Kcg2LnYp9i12YXYqSDYrNmF2YfZiNix2YrY 171 | qSDYo9mE2YXYp9mG2YrYpyDYp9mE2KfYqtit2KfYr9mK2Kkg2YjZhdix2YPY 172 | siDYrdmD2YjZhdiq2YfYpyDZiNin2YTYqNix2YTZhdin2YbYjCDZiNil2K3Y 173 | r9mJINij2YfZhSDYp9mE2YXYr9mGINin2YTYo9mI2LHZiNio2YrYqS4iCiAg 174 | ICB9LCB7CiAgICAgICJAbGFuZ3VhZ2UiIDogImRlIiwKICAgICAgIkB2YWx1 175 | ZSIgOiAiQmVybGluIChbYsmbyZDMr8uIbGnLkG5dKSBpc3QgZGllIEJ1bmRl 176 | c2hhdXB0c3RhZHQgZGVyIEJ1bmRlc3JlcHVibGlrIERldXRzY2hsYW5kIHVu 177 | ZCB6dWdsZWljaCBlaW5lcyBpaHJlciBMw6RuZGVyLiBEaWUgU3RhZHQgQmVy 178 | bGluIGlzdCBtaXQgcnVuZCAzLDUgTWlsbGlvbmVuIEVpbndvaG5lcm4gZGll 179 | IGJldsO2bGtlcnVuZ3NyZWljaHN0ZSB1bmQgbWl0IDg5MiBRdWFkcmF0a2ls 180 | b21ldGVybiBkaWUgZmzDpGNoZW5ncsO2w590ZSBHZW1laW5kZSBEZXV0c2No 181 | bGFuZHMgc293aWUgbmFjaCBFaW53b2huZXJuIGRpZSB6d2VpdGdyw7bDn3Rl 182 | IGRlciBFdXJvcMOkaXNjaGVuIFVuaW9uLiBTaWUgYmlsZGV0IGRhcyBaZW50 183 | cnVtIGRlciBNZXRyb3BvbHJlZ2lvbiBCZXJsaW4vQnJhbmRlbmJ1cmcgKDYg 184 | TWlsbGlvbmVuIEVpbncuKSB1bmQgZGVyIEFnZ2xvbWVyYXRpb24gQmVybGlu 185 | ICg0LDQgTWlsbGlvbmVuIEVpbncuKS4gRGVyIFN0YWR0c3RhYXQgdW50ZXJ0 186 | ZWlsdCBzaWNoIGluIHp3w7ZsZiBCZXppcmtlLiBOZWJlbiBkZW4gRmzDvHNz 187 | ZW4gU3ByZWUgdW5kIEhhdmVsIGJlZmluZGVuIHNpY2ggaW0gU3RhZHRnZWJp 188 | ZXQga2xlaW5lcmUgRmxpZcOfZ2V3w6Rzc2VyIHNvd2llIHphaGxyZWljaGUg 189 | U2VlbiB1bmQgV8OkbGRlci4gVXJrdW5kbGljaCBlcnN0bWFscyBpbSAxMy4g 190 | SmFocmh1bmRlcnQgZXJ3w6RobnQsIHdhciBCZXJsaW4gaW0gVmVybGF1ZiBk 191 | ZXIgR2VzY2hpY2h0ZSB1bmQgaW4gdmVyc2NoaWVkZW5lbiBTdGFhdHNmb3Jt 192 | ZW4gUmVzaWRlbnotIHVuZCBIYXVwdHN0YWR0IEJyYW5kZW5idXJncywgUHJl 193 | dcOfZW5zIHVuZCBkZXMgRGV1dHNjaGVuIFJlaWNocy4gQWIgMTk0OSB3YXIg 194 | ZGVyIE9zdHRlaWwgZGVyIFN0YWR0IGZha3Rpc2NoIEhhdXB0c3RhZHQgZGVy 195 | IERldXRzY2hlbiBEZW1va3JhdGlzY2hlbiBSZXB1Ymxpay4gTWl0IGRlciBk 196 | ZXV0c2NoZW4gV2llZGVydmVyZWluaWd1bmcgaW0gSmFociAxOTkwIHdhciBC 197 | ZXJsaW4gd2llZGVyIGdlc2FtdGRldXRzY2hlIEhhdXB0c3RhZHQgdW5kIHd1 198 | cmRlIGluIGRlciBGb2xnZSBTaXR6IGRlciBCdW5kZXNyZWdpZXJ1bmcsIGRl 199 | cyBCdW5kZXNwcsOkc2lkZW50ZW4sIGRlcyBEZXV0c2NoZW4gQnVuZGVzdGFn 200 | cywgZGVzIEJ1bmRlc3JhdHMgc293aWUgemFobHJlaWNoZXIgQnVuZGVzbWlu 201 | aXN0ZXJpZW4gdW5kIEJvdHNjaGFmdGVuLiBCZXJsaW4gaXN0IGVpbiBldXJv 202 | cMOkaXNjaGVyIEtub3RlbnB1bmt0IGbDvHIgU2NoaWVuZW4tIHVuZCBMdWZ0 203 | dmVya2Voci4gWnUgZGVuIHdpY2h0aWdlbiBXaXJ0c2NoYWZ0c3p3ZWlnZW4g 204 | ZGVyIFN0YWR0IHrDpGhsZW4gdS4gYS4gZGVyIFRvdXJpc211cywgZGllIEty 205 | ZWF0aXYtIHVuZCBLdWx0dXJ3aXJ0c2NoYWZ0LCBkaWUgQmlvdGVjaG5vbG9n 206 | aWUsIGRpZSBNZWRpemludGVjaG5paywgZGllIHBoYXJtYXpldXRpc2NoZSBJ 207 | bmR1c3RyaWUsIGRpZSBJbmZvcm1hdGlvbnMtIHVuZCBLb21tdW5pa2F0aW9u 208 | c3RlY2hub2xvZ2llbiwgZGllIEJhdS0gdW5kIEltbW9iaWxpZW53aXJ0c2No 209 | YWZ0LCBkZXIgSGFuZGVsLCBkaWUgT3B0b2VsZWt0cm9uaWssIGRpZSBFbmVy 210 | Z2lldGVjaG5payBzb3dpZSBkaWUgTWVzc2UtIHVuZCBLb25ncmVzc3dpcnRz 211 | Y2hhZnQuIEJlcmxpbiB6w6RobHQgenUgZGVuIGF1ZnN0cmViZW5kZW4sIGlu 212 | dGVybmF0aW9uYWxlbiBaZW50cmVuIGbDvHIgaW5ub3ZhdGl2ZSBVbnRlcm5l 213 | aG1lbnNncsO8bmRlciB1bmQgdmVyemVpY2huZXQgasOkaHJsaWNoIGhvaGUg 214 | WnV3YWNoc3JhdGVuIGJlaSBkZXIgWmFobCBkZXIgRXJ3ZXJic3TDpHRpZ2Vu 215 | LiBCZXJsaW4gZ2lsdCBhbHMgV2VsdHN0YWR0IGRlciBLdWx0dXIsIFBvbGl0 216 | aWssIE1lZGllbiB1bmQgV2lzc2Vuc2NoYWZ0ZW4uIERpZSBVbml2ZXJzaXTD 217 | pHRlbiwgRm9yc2NodW5nc2VpbnJpY2h0dW5nZW4sIFNwb3J0ZXJlaWduaXNz 218 | ZSB1bmQgTXVzZWVuIEJlcmxpbnMgZ2VuaWXDn2VuIGludGVybmF0aW9uYWxl 219 | biBSdWYuIERpZSBNZXRyb3BvbGUgdHLDpGd0IGRlbiBVTkVTQ08tVGl0ZWwg 220 | U3RhZHQgZGVzIERlc2lnbnMgdW5kIGlzdCBlaW5lcyBkZXIgbWVpc3RiZXN1 221 | Y2h0ZW4gWmVudHJlbiBkZXMgS29udGluZW50cy4gQmVybGlucyBBcmNoaXRl 222 | a3R1ciwgRmVzdGl2YWxzLCBOYWNodGxlYmVuIHVuZCB2aWVsZsOkbHRpZ2Ug 223 | TGViZW5zYmVkaW5ndW5nZW4gc2luZCB3ZWx0d2VpdCBiZWthbm50LiIKICAg 224 | IH0sIHsKICAgICAgIkBsYW5ndWFnZSIgOiAiZW4iLAogICAgICAiQHZhbHVl 225 | IiA6ICJCZXJsaW4gKC9iyZlyy4hsyapuLywgW2LJm8mQzK/LiGxpy5BuXSkg 226 | aXMgdGhlIGNhcGl0YWwgb2YgR2VybWFueSBhbmQgb25lIG9mIHRoZSAxNiBz 227 | dGF0ZXMgb2YgR2VybWFueS4gV2l0aCBhIHBvcHVsYXRpb24gb2YgMy41IG1p 228 | bGxpb24gcGVvcGxlLCBpdCBpcyB0aGUgc2Vjb25kIG1vc3QgcG9wdWxvdXMg 229 | Y2l0eSBwcm9wZXIgYW5kIHRoZSBzZXZlbnRoIG1vc3QgcG9wdWxvdXMgdXJi 230 | YW4gYXJlYSBpbiB0aGUgRXVyb3BlYW4gVW5pb24uIExvY2F0ZWQgaW4gbm9y 231 | dGhlYXN0ZXJuIEdlcm1hbnkgb24gdGhlIGJhbmtzIG9mIFJpdmVycyBTcHJl 232 | ZSBhbmQgSGF2ZWwsIGl0IGlzIHRoZSBjZW50cmUgb2YgdGhlIEJlcmxpbi1C 233 | cmFuZGVuYnVyZyBNZXRyb3BvbGl0YW4gUmVnaW9uLCB3aGljaCBoYXMgYWJv 234 | dXQgc2l4IG1pbGxpb24gcmVzaWRlbnRzIGZyb20gb3ZlciAxODAgbmF0aW9u 235 | cy4gRHVlIHRvIGl0cyBsb2NhdGlvbiBpbiB0aGUgRXVyb3BlYW4gUGxhaW4s 236 | IEJlcmxpbiBpcyBpbmZsdWVuY2VkIGJ5IGEgdGVtcGVyYXRlIHNlYXNvbmFs 237 | IGNsaW1hdGUuIEFyb3VuZCBvbmUtdGhpcmQgb2YgdGhlIGNpdHkncyBhcmVh 238 | IGlzIGNvbXBvc2VkIG9mIGZvcmVzdHMsIHBhcmtzLCBnYXJkZW5zLCByaXZl 239 | cnMgYW5kIGxha2VzLiBGaXJzdCBkb2N1bWVudGVkIGluIHRoZSAxM3RoIGNl 240 | bnR1cnkgYW5kIHNpdHVhdGVkIGF0IHRoZSBjcm9zc2luZyBvZiB0d28gaW1w 241 | b3J0YW50IGhpc3RvcmljIHRyYWRlIHJvdXRlcywgQmVybGluIGJlY2FtZSB0 242 | aGUgY2FwaXRhbCBvZiB0aGUgTWFyZ3JhdmlhdGUgb2YgQnJhbmRlbmJ1cmcg 243 | KDE0MTfigJMxNzAxKSwgdGhlIEtpbmdkb20gb2YgUHJ1c3NpYSAoMTcwMeKA 244 | kzE5MTgpLCB0aGUgR2VybWFuIEVtcGlyZSAoMTg3MeKAkzE5MTgpLCB0aGUg 245 | V2VpbWFyIFJlcHVibGljICgxOTE54oCTMTkzMykgYW5kIHRoZSBUaGlyZCBS 246 | ZWljaCAoMTkzM+KAkzE5NDUpLiBCZXJsaW4gaW4gdGhlIDE5MjBzIHdhcyB0 247 | aGUgdGhpcmQgbGFyZ2VzdCBtdW5pY2lwYWxpdHkgaW4gdGhlIHdvcmxkLiBB 248 | ZnRlciBXb3JsZCBXYXIgSUksIHRoZSBjaXR5IHdhcyBkaXZpZGVkOyBFYXN0 249 | IEJlcmxpbiBiZWNhbWUgdGhlIGNhcGl0YWwgb2YgRWFzdCBHZXJtYW55IHdo 250 | aWxlIFdlc3QgQmVybGluIGJlY2FtZSBhIGRlIGZhY3RvIFdlc3QgR2VybWFu 251 | IGV4Y2xhdmUsIHN1cnJvdW5kZWQgYnkgdGhlIEJlcmxpbiBXYWxsICgxOTYx 252 | 4oCTMTk4OSkgYW5kIEVhc3QgR2VybWFueSB0ZXJyaXRvcnkuIEZvbGxvd2lu 253 | ZyBHZXJtYW4gcmV1bmlmaWNhdGlvbiBpbiAxOTkwLCBCZXJsaW4gd2FzIG9u 254 | Y2UgYWdhaW4gZGVzaWduYXRlZCBhcyB0aGUgY2FwaXRhbCBvZiB1bml0ZWQg 255 | R2VybWFueS4gQmVybGluIGlzIGEgd29ybGQgY2l0eSBvZiBjdWx0dXJlLCBw 256 | b2xpdGljcywgbWVkaWEgYW5kIHNjaWVuY2UuIEl0cyBlY29ub215IGlzIGJh 257 | c2VkIG9uIGhpZ2gtdGVjaCBmaXJtcyBhbmQgdGhlIHNlcnZpY2Ugc2VjdG9y 258 | LCBlbmNvbXBhc3NpbmcgYSBkaXZlcnNlIHJhbmdlIG9mIGNyZWF0aXZlIGlu 259 | ZHVzdHJpZXMsIHJlc2VhcmNoIGZhY2lsaXRpZXMsIG1lZGlhIGNvcnBvcmF0 260 | aW9ucyBhbmQgY29udmVudGlvbiB2ZW51ZXMuIEJlcmxpbiBzZXJ2ZXMgYXMg 261 | YSBjb250aW5lbnRhbCBodWIgZm9yIGFpciBhbmQgcmFpbCB0cmFmZmljIGFu 262 | ZCBoYXMgYSBoaWdobHkgY29tcGxleCBwdWJsaWMgdHJhbnNwb3J0YXRpb24g 263 | bmV0d29yay4gVGhlIG1ldHJvcG9saXMgaXMgYSBwb3B1bGFyIHRvdXJpc3Qg 264 | ZGVzdGluYXRpb24uIFNpZ25pZmljYW50IGluZHVzdHJpZXMgYWxzbyBpbmNs 265 | dWRlIElULCBwaGFybWFjZXV0aWNhbHMsIGJpb21lZGljYWwgZW5naW5lZXJp 266 | bmcsIGNsZWFuIHRlY2gsIGJpb3RlY2hub2xvZ3ksIGNvbnN0cnVjdGlvbiBh 267 | bmQgZWxlY3Ryb25pY3MuIE1vZGVybiBCZXJsaW4gaXMgaG9tZSB0byB3b3Js 268 | ZCByZW5vd25lZCB1bml2ZXJzaXRpZXMsIG9yY2hlc3RyYXMsIG11c2V1bXMs 269 | IGVudGVydGFpbm1lbnQgdmVudWVzIGFuZCBpcyBob3N0IHRvIG1hbnkgc3Bv 270 | cnRpbmcgZXZlbnRzLiBJdHMgdXJiYW4gc2V0dGluZyBoYXMgbWFkZSBpdCBh 271 | IHNvdWdodC1hZnRlciBsb2NhdGlvbiBmb3IgaW50ZXJuYXRpb25hbCBmaWxt 272 | IHByb2R1Y3Rpb25zLiBUaGUgY2l0eSBpcyB3ZWxsIGtub3duIGZvciBpdHMg 273 | ZmVzdGl2YWxzLCBkaXZlcnNlIGFyY2hpdGVjdHVyZSwgbmlnaHRsaWZlLCBj 274 | b250ZW1wb3JhcnkgYXJ0cyBhbmQgYSBoaWdoIHF1YWxpdHkgb2YgbGl2aW5n 275 | LiBPdmVyIHRoZSBsYXN0IGRlY2FkZSBCZXJsaW4gaGFzIHNlZW4gdGhlIGVt 276 | ZXJnZW5jZSBvZiBhIGNvc21vcG9saXRhbiBlbnRyZXByZW5ldXJpYWwgc2Nl 277 | bmUuIgogICAgfSwgewogICAgICAiQGxhbmd1YWdlIiA6ICJlcyIsCiAgICAg 278 | ICJAdmFsdWUiIDogIkJlcmzDrW4gKEJlcmxpbiBlbiBhbGVtw6FuIChBY2Vy 279 | Y2EgZGUgZXN0ZSBzb25pZG8gW2LJm8mQzK/LiGxpy5BuXSApKSBlcyBsYSBj 280 | YXBpdGFsIGRlIEFsZW1hbmlhIHkgdW5vIGRlIGxvcyBkaWVjaXPDqWlzIGVz 281 | dGFkb3MgZmVkZXJhZG9zIGFsZW1hbmVzLiBTZSBsb2NhbGl6YSBhbCBub3Jl 282 | c3RlIGRlIEFsZW1hbmlhLCBhIGVzY2Fzb3MgNzAga20gZGUgbGEgZnJvbnRl 283 | cmEgY29uIFBvbG9uaWEuIFBvciBsYSBjaXVkYWQgZmx1eWVuIGxvcyByw61v 284 | cyBTcHJlZSwgSGF2ZWwsIFBhbmtlLCBEYWhtZSB5IFd1aGxlLiBDb24gdW5h 285 | IHBvYmxhY2nDs24gZGUgMyw0IG1pbGxvbmVzIGRlIGhhYml0YW50ZXMsIEJl 286 | cmzDrW4gZXMgbGEgY2l1ZGFkIG3DoXMgcG9ibGFkYSBkZWwgcGHDrXMsIGFz 287 | w60gY29tbyBsYSBzZWd1bmRhIGNpdWRhZCBlbiB0YW1hw7FvIHkgbGEgcXVp 288 | bnRhIGFnbG9tZXJhY2nDs24gdXJiYW5hIGVudHJlIGxvcyBwYcOtc2VzIGRl 289 | IGxhIFVuacOzbiBFdXJvcGVhLiBGdW5kYWRhIGVuIDEyMzcgY29tbyBDw7Zs 290 | bG4sIEJlcmzDrW4gZnVlIHN1Y2VzaXZhbWVudGUgY2FwaXRhbCBkZWwgUmVp 291 | bm8gZGUgUHJ1c2lhICgxNzAxLTE5MTgpLCBkZSBsYSBSZXDDumJsaWNhIGRl 292 | IFdlaW1hciAoMTkxOeKAkzE5MzMpIHkgZGVsIFRlcmNlciBSZWljaCAoMTkz 293 | M+KAkzE5NDUpLiBEZXNwdcOpcyBkZSBsYSBTZWd1bmRhIEd1ZXJyYSBNdW5k 294 | aWFsLCBsYSBjaXVkYWQgZnVlIGRpdmlkaWRhOyBsYSBwYXJ0ZSBlc3RlIGRl 295 | IGxhIGNpdWRhZCBzZSBjb252aXJ0acOzIGVuIGxhIGNhcGl0YWwgZGUgbGEg 296 | UmVww7pibGljYSBEZW1vY3LDoXRpY2EgQWxlbWFuYSwgbWllbnRyYXMgcXVl 297 | IGxhIHJlZ2nDs24gb2VzdGUgZGUgbGEgY2l1ZGFkIHNlIGNvbnZpcnRpw7Mg 298 | ZW4gdW4gZW5jbGF2ZSBkZSBsYSBSZXDDumJsaWNhIEZlZGVyYWwgZGUgQWxl 299 | bWFuaWEgZW4gZWwgaW50ZXJpb3IgZGUgbGEgQWxlbWFuaWEgT3JpZW50YWwu 300 | IEJlcmzDrW4gZXMgdW5hIGNpdWRhZCBtdW5kaWFsIHkgdW4gY2VudHJvIGN1 301 | bHR1cmFsIHkgYXJ0w61zdGljbyBkZSBwcmltZXIgbml2ZWwuIEVzIHVuYSBk 302 | ZSBsYXMgY2l1ZGFkZXMgbcOhcyBpbmZsdXllbnRlcyBlbiBlbCDDoW1iaXRv 303 | IHBvbMOtdGljbyBkZSBsYSBVbmnDs24gRXVyb3BlYSB5IGVuIDIwMDYgZnVl 304 | IGVsZWdpZGEgQ2l1ZGFkIENyZWF0aXZhIHBvciBsYSBVbmVzY28uIEVuIDIw 305 | MDkgbGEgY2l1ZGFkIHJlY2liacOzIGVsIFByZW1pbyBQcsOtbmNpcGUgZGUg 306 | QXN0dXJpYXMgZGUgbGEgQ29uY29yZGlhLiIKICAgIH0sIHsKICAgICAgIkBs 307 | YW5ndWFnZSIgOiAiZnIiLAogICAgICAiQHZhbHVlIiA6ICJCZXJsaW4gKHBy 308 | b25vbmPDqSBbYsmbyoEubMmbzINdIDsgZW4gYWxsZW1hbmQgQmVybGluIFti 309 | yZvJkMyvLsuIbGnLkG5dICkgZXN0IGxhIGNhcGl0YWxlIGV0IGxhIHBsdXMg 310 | Z3JhbmRlIHZpbGxlIGQnQWxsZW1hZ25lLiBTaXR1w6llIGRhbnMgbGUgbm9y 311 | ZC1lc3QgZHUgcGF5cywgZWxsZSBmb3JtZSB1biBsYW5kICjDiXRhdCBmw6lk 312 | w6lyw6kpIMOgIHBhcnQgZW50acOocmUgZXQgY29tcHRlIGVudmlyb24gMyw1 313 | IG1pbGxpb25zIGQnaGFiaXRhbnRzLiBTZXMgaGFiaXRhbnRzIHMnYXBwZWxs 314 | ZW50IGxlcyBCZXJsaW5vaXMuIEJlcmxpbiBlc3QgbGEgZGV1eGnDqG1lIHZp 315 | bGxlIGV0IGxhIHNlcHRpw6htZSBhZ2dsb23DqXJhdGlvbiBsYSBwbHVzIHBl 316 | dXBsw6llIGRlIGwnVW5pb24gZXVyb3DDqWVubmUuIEwnYWdnbG9tw6lyYXRp 317 | b24gZGUgQmVybGluIHMnw6l0ZW5kIHN1ciAzIDczNCBrbTIgZXQgY29tcHRl 318 | IDQsNCBtaWxsaW9ucyBkJ2hhYml0YW50cywgZXQgbGEgcsOpZ2lvbiBtw6l0 319 | cm9wb2xpdGFpbmUgZGUgQmVybGluLUJyYW5kZWJvdXJnIHF1aSBjdW11bGUg 320 | bGVzIEzDpG5kZXIgZGUgQmVybGluIGV0IGRlIEJyYW5kZWJvdXJnIHJlZ3Jv 321 | dXBlIGF1IHRvdGFsIHByw6hzIGRlIDYgbWlsbGlvbnMgZCdoYWJpdGFudHMu 322 | IEZvbmTDqWUgYXUgWElJSWUgc2nDqGNsZSwgQmVybGluIGEgw6l0w6kgc3Vj 323 | Y2Vzc2l2ZW1lbnQgY2FwaXRhbGUgZHUgcm95YXVtZSBkZSBQcnVzc2UgKDE3 324 | MDEtMTg3MSksIGRlIGwnRW1waXJlIGFsbGVtYW5kICgxODcxLTE5MTgpLCBk 325 | ZSBsYSBSw6lwdWJsaXF1ZSBkZSBXZWltYXIgKDE5MTktMTkzMykgZXQgZHUg 326 | VHJvaXNpw6htZSBSZWljaCAoMTkzMy0xOTQ1KS4gQXByw6hzIDE5NDUgZXQg 327 | anVzcXUnw6AgbGEgY2h1dGUgZHUgTXVyIGRlIEJlcmxpbiBlbiAxOTg5LCBs 328 | YSB2aWxsZSBlc3QgcGFydGFnw6llIGVuIHF1YXRyZSBzZWN0ZXVycyBkJ29j 329 | Y3VwYXRpb24uIFBlbmRhbnQgbGEgR3VlcnJlIGZyb2lkZSwgbGUgc2VjdGV1 330 | ciBzb3Zpw6l0aXF1ZSBkZSBsYSB2aWxsZSwgbm9tbcOpIEJlcmxpbi1Fc3Qs 331 | IGVzdCBkZXZlbnUgbGEgY2FwaXRhbGUgZGUgbGEgUsOpcHVibGlxdWUgZMOp 332 | bW9jcmF0aXF1ZSBhbGxlbWFuZGUsIHRhbmRpcyBxdWUgQmVybGluLU91ZXN0 333 | IMOpdGFpdCBwb2xpdGlxdWVtZW50IHJhdHRhY2jDqWUgw6AgbGEgUsOpcHVi 334 | bGlxdWUgZsOpZMOpcmFsZSBkJ0FsbGVtYWduZSwgZGV2ZW5hbnQgYWluc2kg 335 | dW4gYmFzdGlvbiBhdmFuY8OpIGR1IMKrIE1vbmRlIGxpYnJlIMK7IMOgIGwn 336 | aW50w6lyaWV1ciBkdSBCbG9jIGNvbW11bmlzdGUuIEFwcsOocyBsYSBjaHV0 337 | ZSBkdSBtdXIsIEJlcmxpbiByZWRldmludCwgZW4gMTk5MCwgbGEgY2FwaXRh 338 | bGUgZGUgbCdBbGxlbWFnbmUgYWxvcnMgcsOpdW5pZmnDqWUsIGV0IGxlcyBw 339 | cmluY2lwYWxlcyBpbnN0aXR1dGlvbnMgZsOpZMOpcmFsZXMgeSBlbW3DqW5h 340 | Z8OocmVudCBlbiAxOTk5LiBCZXJsaW4gZXN0IHVuZSB2aWxsZSBtb25kaWFs 341 | ZSBjdWx0dXJlbGxlIGV0IGFydGlzdGlxdWUgZGUgcHJlbWllciBwbGFuLiBM 342 | YSB2aWxsZSBhYnJpdGUgMTY2IG11c8OpZXMsIDE0MiBiaWJsaW90aMOocXVl 343 | cyBldCA2MCB0aMOpw6J0cmVzLiBFbiAyMDE0LCBCZXJsaW4gYSBhY2N1ZWls 344 | bGkgMTEsODcgbWlsbGlvbnMgZGUgdmlzaXRldXJzICgrNCw4ICUgcGx1cyBx 345 | dSdlbiAyMDEzKSwgZG9udCA0LDUyIG1pbGxpb25zIHZpc2l0ZXVycyDDqXRy 346 | YW5nZXJzICgrNSwyICUpLiIKICAgIH0sIHsKICAgICAgIkBsYW5ndWFnZSIg 347 | OiAiaXQiLAogICAgICAiQHZhbHVlIiA6ICJCZXJsaW5vIChpbiB0ZWRlc2Nv 348 | OiBCZXJsaW4sIC9iyZvJkMyqIMuIbGnLkG4vLCApIMOoIGxhIG1hZ2dpb3Jl 349 | IGNpdHTDoCBlIG5lbCBjb250ZW1wbyB1biBCdW5kZXNsYW5kIGRlbGxhIEdl 350 | cm1hbmlhLCBxdWluZGkgdW5hIGNpdHTDoC1zdGF0by4gQ2FwaXRhbGUgZmVk 351 | ZXJhbGUgZGVsbGEgUmVwdWJibGljYSBGZWRlcmFsZSBkaSBHZXJtYW5pYSBl 352 | IHNlZGUgZGVsIHN1byBnb3Zlcm5vLCDDqCB1bm8gZGVpIHBpw7kgaW1wb3J0 353 | YW50aSBjZW50cmkgcG9saXRpY2ksIGN1bHR1cmFsaSwgc2NpZW50aWZpY2ks 354 | IGZpZXJpc3RpY2kgZSBtZWRpYXRpY2kgZCdFdXJvcGEgZSwgZG9wbyBMb25k 355 | cmEsIGlsIHNlY29uZG8gY29tdW5lIHBpw7kgcG9wb2xvc28gZGVsbCdVbmlv 356 | bmUgZXVyb3BlYSwgY29uIDMgNTMxIDIwMSBhYml0YW50aS4gTCdhcmVhIG1l 357 | dHJvcG9saXRhbmEgaGEgdW5hIHN1cGVyZmljaWUgY29tcGxlc3NpdmEgZGkg 358 | MiA4NTEga23CsiBlZCB1bmEgcG9wb2xhemlvbmUgZGkgNCA0NjIgMTY2IGFi 359 | aXRhbnRpLCBtZW50cmUgbGEgcmVnaW9uZSBtZXRyb3BvbGl0YW5hIGRpIEJl 360 | cmxpbm8gZSBCcmFuZGVidXJnbyBoYSB1bmEgc3VwZXJmaWNpZSBkaSAzMCAz 361 | NzAga23CsiBlZCB1bmEgcG9wb2xhemlvbmUgZGkgNiAwMjQgMDAwIGFiaXRh 362 | bnRpLiIKICAgIH0sIHsKICAgICAgIkBsYW5ndWFnZSIgOiAiamEiLAogICAg 363 | ICAiQHZhbHVlIiA6ICLjg5njg6vjg6rjg7PvvIjni6w6IEJlcmxpbiBbYsmb 364 | yZDMr8uIbGnLkG5d44CB5Lyv5p6X77yJ44Gv44CB44OJ44Kk44OE44Gu6YO9 365 | 5biC44Gn5ZCM5Zu944Gu6aaW6YO944Gn44GC44KL44CCMTbjgYLjgovpgKPp 366 | gqblt57jga7jgYbjgaHjga7kuIDjgaTjgafjgIHluILln5/kurrlj6Pjga8z 367 | NTDkuIfkurrjgajjg4njgqTjg4Tjgafjga/mnIDlpKfjga7pg73luILjgafm 368 | rKflt57pgKPlkIjjga7luILln5/kurrlj6Pjgafjga/jg63jg7Pjg4njg7Pj 369 | gavmrKHjgYTjgacy55Wq55uu44Gr5aSa44GP44CB6YO95biC55qE5Zyw5Z+f 370 | 44Gu5Lq65Y+j44GvN+eVquebruOBq+WkmuOBhOOAgiIKICAgIH0sIHsKICAg 371 | ICAgIkBsYW5ndWFnZSIgOiAibmwiLAogICAgICAiQHZhbHVlIiA6ICJCZXJs 372 | aWpuIChEdWl0czogQmVybGluKSBpcyBkZSBob29mZHN0YWQgdmFuIER1aXRz 373 | bGFuZCBlbiBhbHMgc3RhZHN0YWF0IGVlbiBkZWVsc3RhYXQgdmFuIGRhdCBs 374 | YW5kLiBNZXQgMy40MzcuOTE2IGlud29uZXJzIGlzIEJlcmxpam4gdGV2ZW5z 375 | IGRlIGdyb290c3RlIHN0YWQgdmFuIGhldCBsYW5kIGVuIGRlIG9wIMOpw6lu 376 | IG5hIGdyb290c3RlIHN0YWQgaW4gZGUgRXVyb3Blc2UgVW5pZS4gRGUgc3Rh 377 | ZCBsaWd0IGluIGhldCBub29yZG9vc3RlbiB2YW4gRHVpdHNsYW5kLCBhYW4g 378 | ZGUgcml2aWVyIGRlIFNwcmVlIGVuIHdvcmR0IG9tc2xvdGVuIGRvb3IgZGUg 379 | ZGVlbHN0YWF0IEJyYW5kZW5idXJnLCB3YWFydmFuIHplIHNpbmRzIDE5MjAg 380 | Z2VlbiBkZWVsIG1lZXIgdWl0bWFha3QuIEluIHppam4gZ2VzY2hpZWRlbmlz 381 | LCBkaWUgdGVydWdnYWF0IHRvdCBkZSBkZXJ0aWVuZGUgZWV1dywgd2FzIEJl 382 | cmxpam4gZGUgaG9vZmRzdGFkIHZhbiBQcnVpc2VuICgxNzAx4oCTMTkxOCks 383 | IGhldCBEdWl0c2UgS2VpemVycmlqayAoMTg3MeKAkzE5MTgpLCBkZSBXZWlt 384 | YXJyZXB1YmxpZWsgKDE5MTnigJMxOTMzKSBlbiBuYXppLUR1aXRzbGFuZCAo 385 | MTkzM+KAkzE5NDUpLiBOYSBkZSBUd2VlZGUgV2VyZWxkb29ybG9nIHdhcyBC 386 | ZXJsaWpuIGdlZHVyZW5kZSBtZWVyIGRhbiB2ZWVydGlnIGphYXIgZWVuIHZl 387 | cmRlZWxkZSBzdGFkLCB3YWFyYmlqIGhldCBvb3N0ZWxpamtlIGRlZWwgYWxz 388 | IGhvb2Zkc3RhZCBmdW5nZWVyZGUgdmFuIGRlIER1aXRzZSBEZW1vY3JhdGlz 389 | Y2hlIFJlcHVibGllayBlbiBXZXN0LUJlcmxpam4gZWVuIGRlIGZhY3RvIGV4 390 | Y2xhdmUgdmFuIFdlc3QtRHVpdHNsYW5kIHdhcy4gTmEgZGUgRHVpdHNlIGhl 391 | cmVuaWdpbmcgaW4gMTk5MCB3ZXJkIEJlcmxpam4gZGUgaG9vZmRzdGFkIHZh 392 | biBkZSBCb25kc3JlcHVibGllayBEdWl0c2xhbmQgZW4gZGUgemV0ZWwgdmFu 393 | IGhldCBwYXJsZW1lbnQsIGRlIGRlZWxzdGFhdHZlcnRlZ2Vud29vcmRpZ2lu 394 | ZyBlbiBoZXQgc3RhYXRzaG9vZmQuIEJlcmxpam4gaXMgZWVuIG1ldHJvcG9v 395 | bCBlbiBnZWxkdCBpbiBFdXJvcGEgYWxzIGVlbiB2YW4gZGUgZ3Jvb3RzdGUg 396 | Y3VsdHVyZWxlLCBwb2xpdGlla2UgZW4gd2V0ZW5zY2hhcHBlbGlqa2UgY2Vu 397 | dHJhLiBEZSBzdGFkIGlzIG9vayBiZWtlbmQgdmFud2VnZSBoZXQgaG9vZy1v 398 | bnR3aWtrZWxkZSBjdWx0dXJlbGUgbGV2ZW4gKGZlc3RpdmFscywgbmFjaHRs 399 | ZXZlbiwgbXVzZWEsIGt1bnN0dGVudG9vbnN0ZWxsaW5nZW4gZW56LikgZW4g 400 | ZGUgbGliZXJhbGUgbGV2ZW5zc3RpamwsIG1vZGVybmUgWmVpdGdlaXN0IGVu 401 | IGRlIGxhZ2Uga29zdGVuLiBCb3ZlbmRpZW4gaXMgQmVybGlqbiBlZW4gdmFu 402 | IGRlIGdyb2Vuc3RlIHN0ZWRlbiB2YW4gRXVyb3BhOiAyMiUgdmFuIEJlcmxp 403 | am4gYmVzdGFhdCB1aXQgbmF0dXVyIGVuIHBhcmtlbiBlbiA2JSB1aXQgbWVy 404 | ZW4sIHJpdmllcmVuIGVuIGthbmFsZW4uIgogICAgfSwgewogICAgICAiQGxh 405 | bmd1YWdlIiA6ICJwbCIsCiAgICAgICJAdmFsdWUiIDogIkJlcmxpbiDigJMg 406 | c3RvbGljYSwgc2llZHppYmEgcnrEhWR1IFJlcHVibGlraSBGZWRlcmFsbmVq 407 | IE5pZW1pZWMuIE5handpxJlrc3plIG1pYXN0byBOaWVtaWVjLCBuYSBwcmF3 408 | YWNoIGtyYWp1IHp3acSFemtvd2Vnby4gWmFqbXVqZSBwb3dpZXJ6Y2huacSZ 409 | IG9rLiA4OTIga23CsiwgemFtaWVzemt1amUgamUgMyw0IG1sbiBvc8OzYi4g 410 | SmVzdCB0cnplY2ltIG5handpxJlrc3p5bSAocG8gTG9uZHluaWUgaSBQYXJ5 411 | xbx1KSBtaWFzdGVtIHcgVW5paSBFdXJvcGVqc2tpZWouIEJlcmxpbiBqZXN0 412 | IHBvZHppZWxvbnkgbmEgZHdhbmHFm2NpZSBva3LEmWfDs3cgYWRtaW5pc3Ry 413 | YWN5am55Y2ggKEJlemlyaykuIFByemV6IHByemVzdHJ6ZcWEIG1pZWpza8SF 414 | IHByemVwxYJ5d2FqxIUgbS5pbi4gcnpla2kgU3ByZXdhIGkgSGF3ZWxhLCBh 415 | IHBvbmFkdG8gem5hamR1amUgc2nEmSB3aWVsZSBqZXppb3IgaSB6YXRvaywg 416 | dyB0eW0gbmFqd2nEmWtzemUgTcO8Z2dlbHNlZS4gUGllcndzemEgd3ptaWFu 417 | a2EgbyBtaWXFm2NpZSBwb2Nob2R6aSB6IDEyMzcuIEJlcmxpbiBwZcWCbmnF 418 | giByb2zEmSBoaXN0b3J5Y3puZWogc3RvbGljeSBCcmFuZGVuYnVyZ2lpLCBQ 419 | cnVzLCBDZXNhcnN0d2EgTmllbWllY2tpZWdvLCBSZXB1Ymxpa2kgV2VpbWFy 420 | c2tpZWogaSBJSUkgUnplc3p5LiBQbyAxOTQ1IHdzY2hvZG5pYSBjesSZxZvE 421 | hyBtaWFzdGEgYnnFgmEgc3RvbGljxIUgTmllbWllY2tpZWogUmVwdWJsaWtp 422 | IERlbW9rcmF0eWN6bmVqLCBuYXRvbWlhc3QgcG96b3N0YcWCYSB0d29yennF 423 | gmEgQmVybGluIFphY2hvZG5pIOKAkyBvdG9jem9uYSBtdXJlbSAob2QgMTk2 424 | MSkgZW5rbGF3YSBuYSB0ZXJlbmllIE5SRC4gUG8gemplZG5vY3plbml1IE5p 425 | ZW1pZWMgdyAxOTkwIEJlcmxpbiB6b3N0YcWCIHBvbm93bmllIHN0b2xpY8SF 426 | IE5pZW1pZWMsIHNpZWR6aWLEhSBwcmV6eWRlbnRhIChvZCAxOTk0KSwgbmll 427 | bWllY2tpZWdvIEJ1bmRlc3RhZ3UgKG9kIDE5OTkpIGkgQnVuZGVzcmF0dSAo 428 | b2QgMjAwMCkuIEJlcmxpbiBqZXN0IGplZG7EhSB6IHdhxbxuaWVqc3p5Y2gg 429 | dyBFdXJvcGllIG1ldHJvcG9saWkgZ2xvYmFsbnljaCwgcG9uYWR0byB3YcW8 430 | bnltIHfEmXrFgmVtIGtvbXVuaWthY3lqbnltIE5pZW1pZWMgaSBFdXJvcHks 431 | IHphcsOzd25vIGtvbGVqb3d5bSwgbG90bmljenltIGkgZHJvZ293eW0uIFdh 432 | xbxueSBvxZtyb2RlayBuYXVrb3d5LCBrdWx0dXJhbG55IGkgYXJ0eXN0eWN6 433 | bnkgKG0uaW4uIEt1bHR1cmZvcnVtIGkgTXVzZXVtc2luc2VsKS4iCiAgICB9 434 | LCB7CiAgICAgICJAbGFuZ3VhZ2UiIDogInB0IiwKICAgICAgIkB2YWx1ZSIg 435 | OiAiQmVybGltIChlbSBhbGVtw6NvIEJlcmxpbikgw6kgYSBjYXBpdGFsIGUg 436 | dW0gZG9zIGRlemVzc2VpcyBlc3RhZG9zIGRhIEFsZW1hbmhhLiBDb20gdW1h 437 | IHBvcHVsYcOnw6NvIGRlIDMsNSBtaWxow7VlcyBkZW50cm8gZGUgbGltaXRl 438 | cyBkYSBjaWRhZGUsIMOpIGEgbWFpb3IgY2lkYWRlIGRvIHBhw61zLCBhbMOp 439 | bSBkZSBzZXIgYSBzZWd1bmRhIG1haXMgcG9wdWxvc2EgZSBhIHPDqXRpbWEg 440 | w6FyZWEgdXJiYW5hIG1haXMgcG92b2FkYSBkYSBVbmnDo28gRXVyb3BlaWEu 441 | IFNpdHVhZGEgbm8gbm9yZGVzdGUgZGEgQWxlbWFuaGEsIMOpIG8gY2VudHJv 442 | IGRhIMOhcmVhIG1ldHJvcG9saXRhbmEgZGUgQmVybGltLUJyYW5kZW1idXJn 443 | bywgcXVlIGluY2x1aSA1IG1pbGjDtWVzIGRlIHBlc3NvYXMgZGUgbWFpcyBk 444 | ZSAxOTAgbmHDp8O1ZXMuIExvY2FsaXphZGEgbmEgZ3JhbmRlIHBsYW7DrWNp 445 | ZSBldXJvcGVpYSwgQmVybGltIMOpIGluZmx1ZW5jaWFkYSBwb3IgdW0gY2xp 446 | bWEgdGVtcGVyYWRvIHNhem9uYWwuIENlcmNhIGRlIHVtIHRlcsOnbyBkYSDD 447 | oXJlYSBkYSBjaWRhZGUgw6kgY29tcG9zdGEgcG9yIGZsb3Jlc3RhcywgcGFy 448 | cXVlcywgamFyZGlucywgcmlvcyBlIGxhZ29zLiBEb2N1bWVudGFkYSBwZWxh 449 | IHByaW1laXJhIHZleiBubyBzw6ljdWxvIFhJSUksIEJlcmxpbSBmb2kgc3Vj 450 | ZXNzaXZhbWVudGUgYSBjYXBpdGFsIGRvIFJlaW5vIGRhIFByw7pzc2lhICgx 451 | NzAxLTE5MTgpLCBkbyBJbXDDqXJpbyBBbGVtw6NvICgxODcxLTE5MTgpLCBk 452 | YSBSZXDDumJsaWNhIGRlIFdlaW1hciAoMTkxOS0xOTMzKSBlIGRvIFRlcmNl 453 | aXJvIFJlaWNoICgxOTMzLTE5NDUpLiBBcMOzcyBhIFNlZ3VuZGEgR3VlcnJh 454 | IE11bmRpYWwsIGEgY2lkYWRlIGZvaSBkaXZpZGlkYTsgQmVybGltIE9yaWVu 455 | dGFsIHNlIHRvcm5vdSBhIGNhcGl0YWwgZGEgQWxlbWFuaGEgT3JpZW50YWws 456 | IGVucXVhbnRvIEJlcmxpbSBPY2lkZW50YWwgc2UgdG9ybm91IHVtIGV4Y2xh 457 | dmUgZGEgQWxlbWFuaGEgT2NpZGVudGFsLCBjZXJjYWRhIHBlbG8gbXVybyBk 458 | ZSBCZXJsaW0sIGVudHJlIG9zIGFub3MgZGUgMTk2MS0xOTg5LCBlbnF1YW50 459 | byBhIGNpZGFkZSBkZSBCb25hIHRvcm5vdS1zZSBhIGNhcGl0YWwgZGEgQWxl 460 | bWFuaGEgT2NpZGVudGFsLiBBcMOzcyBhIHJldW5pZmljYcOnw6NvIGFsZW3D 461 | oyBlbSAxOTkwLCBhIGNpZGFkZSByZWN1cGVyb3UgbyBzZXUgZXN0YXR1dG8s 462 | IGNvbW8gYSBjYXBpdGFsIGRhIFJlcMO6YmxpY2EgRmVkZXJhbCBkYSBBbGVt 463 | YW5oYSwgc2VkaWFuZG8gMTQ3IGVtYmFpeGFkYXMgZXN0cmFuZ2VpcmFzLiBC 464 | ZXJsaW0gw6kgdW1hIGNpZGFkZSBnbG9iYWwgZSB1bSBkb3MgbWFpcyBpbmZs 465 | dWVudGVzIGNlbnRyb3MgbXVuZGlhaXMgZGUgY3VsdHVyYSwgcG9sw610aWNh 466 | LCBtw61kaWEgZSBjacOqbmNpYS4gU3VhIGVjb25vbWlhIMOpIGJhc2VhZGEg 467 | cHJpbmNpcGFsbWVudGUgbm8gc2V0b3IgZGUgc2VydmnDp29zLCBhYnJhbmdl 468 | bmRvIHVtYSB2YXJpYWRhIGdhbWEgZGUgaW5kw7pzdHJpYXMgY3JpYXRpdmFz 469 | LCBhcyBjb3Jwb3Jhw6fDtWVzIGRlIG3DrWRpYSBlIGxvY2FpcyBkZSBjb252 470 | ZW7Dp8O1ZXMuIEJlcmxpbSB0YW1iw6ltIHNlcnZlIGNvbW8gdW0gaHViIGNv 471 | bnRpbmVudGFsIHBhcmEgbyB0cmFuc3BvcnRlIGHDqXJlbyBlIGZlcnJvdmnD 472 | oXJpbywgZSDDqSB1bSBkZXN0aW5vIHR1csOtc3RpY28gcG9wdWxhci4gQXMg 473 | aW5kw7pzdHJpYXMgc2lnbmlmaWNhdGl2YXMgaW5jbHVlbSBUSSwgZmFybWFj 474 | w6p1dGljYXMsIGVuZ2VuaGFyaWEgYmlvbcOpZGljYSwgYmlvdGVjbm9sb2dp 475 | YSwgZWxldHLDtG5pY2EsIGVuZ2VuaGFyaWEgZGUgdHLDoWZlZ28gZSBlbmVy 476 | Z2lhIHJlbm92w6F2ZWwuIEEgY2lkYWRlIHNlcnZlIGNvbW8gdW0gaW1wb3J0 477 | YW50ZSBjZW50cm8gZG8gdHJhbnNwb3J0ZSBjb250aW5lbnRhbCBlIMOpIGEg 478 | c2VkZSBkZSBhbGd1bWFzIGRhcyBtYWlzIGltcG9ydGFudGVzIHVuaXZlcnNp 479 | ZGFkZXMsIGV2ZW50b3MgZXNwb3J0aXZvcywgb3JxdWVzdHJhcyBlIG11c2V1 480 | cy4gTyByw6FwaWRvIGRlc2Vudm9sdmltZW50byBkYSBtZXRyw7Nwb2xlIGF0 481 | cmFpdSB1bWEgcmVwdXRhw6fDo28gaW50ZXJuYWNpb25hbCBhb3Mgc2V1cyBm 482 | ZXN0aXZhaXMsIGFycXVpdGV0dXJhIGNvbnRlbXBvcsOibmVhIGUgdmlkYSBu 483 | b3R1cm5hLCBzZW5kbyB1bSBncmFuZGUgY2VudHJvIHR1csOtc3RpY28gZSBt 484 | b3JhZGlhIHBhcmEgcGVzc29hcyBkZSAxODAgbmHDp8O1ZXMgZGlmZXJlbnRl 485 | cy4iCiAgICB9IF0sCiAgICAiaHR0cDovL2RicGVkaWEub3JnL29udG9sb2d5 486 | L2FyZWFDb2RlIiA6IFsgewogICAgICAiQHZhbHVlIiA6ICIwMzAiCiAgICB9 487 | IF0sCiAgICAiaHR0cDovL2RicGVkaWEub3JnL29udG9sb2d5L2FyZWFUb3Rh 488 | bCIgOiBbIHsKICAgICAgIkB0eXBlIiA6ICJodHRwOi8vd3d3LnczLm9yZy8y 489 | MDAxL1hNTFNjaGVtYSNkb3VibGUiLAogICAgICAiQHZhbHVlIiA6ICI4OTE4 490 | NTAwMDAiCiAgICB9IF0sCiAgICAiaHR0cDovL2RicGVkaWEub3JnL29udG9s 491 | b2d5L2NvdW50cnkiIDogWyB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9kYnBl 492 | ZGlhLm9yZy9yZXNvdXJjZS9HZXJtYW55IgogICAgfSBdLAogICAgImh0dHA6 493 | Ly9kYnBlZGlhLm9yZy9vbnRvbG9neS9kZW1vbnltIiA6IFsgewogICAgICAi 494 | QGxhbmd1YWdlIiA6ICJlbiIsCiAgICAgICJAdmFsdWUiIDogIkJlcmxpbmVy 495 | IgogICAgfSBdLAogICAgImh0dHA6Ly9kYnBlZGlhLm9yZy9vbnRvbG9neS9l 496 | bGV2YXRpb24iIDogWyB7CiAgICAgICJAdHlwZSIgOiAiaHR0cDovL3d3dy53 497 | My5vcmcvMjAwMS9YTUxTY2hlbWEjZG91YmxlIiwKICAgICAgIkB2YWx1ZSIg 498 | OiAiMzQiCiAgICB9IF0sCiAgICAiaHR0cDovL2RicGVkaWEub3JnL29udG9s 499 | b2d5L2xlYWRlciIgOiBbIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2RicGVk 500 | aWEub3JnL3Jlc291cmNlL01pY2hhZWxfTcO8bGxlcl8ocG9saXRpY2lhbiki 501 | CiAgICB9IF0sCiAgICAiaHR0cDovL2RicGVkaWEub3JnL29udG9sb2d5L2xl 502 | YWRlclBhcnR5IiA6IFsgewogICAgICAiQGlkIiA6ICJodHRwOi8vZGJwZWRp 503 | YS5vcmcvcmVzb3VyY2UvQ2hyaXN0aWFuX0RlbW9jcmF0aWNfVW5pb25fb2Zf 504 | R2VybWFueSIKICAgIH0sIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2RicGVk 505 | aWEub3JnL3Jlc291cmNlL1NvY2lhbF9EZW1vY3JhdGljX1BhcnR5X29mX0dl 506 | cm1hbnkiCiAgICB9IF0sCiAgICAiaHR0cDovL2RicGVkaWEub3JnL29udG9s 507 | b2d5L2xlYWRlclRpdGxlIiA6IFsgewogICAgICAiQGxhbmd1YWdlIiA6ICJl 508 | biIsCiAgICAgICJAdmFsdWUiIDogIkdvdmVybmluZyBNYXlvciIKICAgIH0g 509 | XSwKICAgICJodHRwOi8vZGJwZWRpYS5vcmcvb250b2xvZ3kvcG9wdWxhdGlv 510 | blRvdGFsIiA6IFsgewogICAgICAiQHR5cGUiIDogImh0dHA6Ly93d3cudzMu 511 | b3JnLzIwMDEvWE1MU2NoZW1hI25vbk5lZ2F0aXZlSW50ZWdlciIsCiAgICAg 512 | ICJAdmFsdWUiIDogIjM1NjIxNjYiCiAgICB9IF0sCiAgICAiaHR0cDovL2Ri 513 | cGVkaWEub3JnL29udG9sb2d5L3Bvc3RhbENvZGUiIDogWyB7CiAgICAgICJA 514 | dmFsdWUiIDogIjEwMTE14oCTMTQxOTkiCiAgICB9IF0sCiAgICAiaHR0cDov 515 | L2RicGVkaWEub3JnL29udG9sb2d5L3NvdW5kUmVjb3JkaW5nIiA6IFsgewog 516 | ICAgICAiQGlkIiA6ICJodHRwOi8vZGJwZWRpYS5vcmcvcmVzb3VyY2UvQmVy 517 | bGluX18xIgogICAgfSBdLAogICAgImh0dHA6Ly9kYnBlZGlhLm9yZy9vbnRv 518 | bG9neS90aHVtYm5haWwiIDogWyB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9j 519 | b21tb25zLndpa2ltZWRpYS5vcmcvd2lraS9TcGVjaWFsOkZpbGVQYXRoL0Nv 520 | YXRfb2ZfYXJtc19vZl9CZXJsaW4uc3ZnP3dpZHRoPTMwMCIKICAgIH0gXSwK 521 | ICAgICJodHRwOi8vZGJwZWRpYS5vcmcvb250b2xvZ3kvd2lraVBhZ2VFeHRl 522 | cm5hbExpbmsiIDogWyB7CiAgICAgICJAaWQiIDogImh0dHA6Ly93d3cuYmVy 523 | bGluLmRlL2VuLyIKICAgIH0sIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL3d3 524 | dy5ub3d0aW1lLnh5ei9iZXJsaW4tOTQyMTI1Lmh0bSIKICAgIH0gXSwKICAg 525 | ICJodHRwOi8vZGJwZWRpYS5vcmcvb250b2xvZ3kvd2lraVBhZ2VJRCIgOiBb 526 | IHsKICAgICAgIkB0eXBlIiA6ICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hN 527 | TFNjaGVtYSNpbnRlZ2VyIiwKICAgICAgIkB2YWx1ZSIgOiAiMzM1NCIKICAg 528 | IH0gXSwKICAgICJodHRwOi8vZGJwZWRpYS5vcmcvb250b2xvZ3kvd2lraVBh 529 | Z2VSZXZpc2lvbklEIiA6IFsgewogICAgICAiQHR5cGUiIDogImh0dHA6Ly93 530 | d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI2ludGVnZXIiLAogICAgICAiQHZh 531 | bHVlIiA6ICI3MDgxNjgzMDMiCiAgICB9IF0sCiAgICAiaHR0cDovL2RicGVk 532 | aWEub3JnL3Byb3BlcnR5L2FyZWEiIDogWyB7CiAgICAgICJAdHlwZSIgOiAi 533 | aHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjZG91YmxlIiwKICAg 534 | ICAgIkB2YWx1ZSIgOiAiODkxLjg1IgogICAgfSBdLAogICAgImh0dHA6Ly9k 535 | YnBlZGlhLm9yZy9wcm9wZXJ0eS9kZXNjcmlwdGlvbiIgOiBbIHsKICAgICAg 536 | IkBsYW5ndWFnZSIgOiAiZW4iLAogICAgICAiQHZhbHVlIiA6ICJTYW1wbGUg 537 | b2YgXCJIZXJvZXNcIiAuIEEgc29uZyBmcm9tIERhdmlkIEJvd2llJ3MgQmVy 538 | bGluIFRyaWxvZ3kgZXJhLiIKICAgIH0gXSwKICAgICJodHRwOi8vZGJwZWRp 539 | YS5vcmcvcHJvcGVydHkvZWxldmF0aW9uIiA6IFsgewogICAgICAiQHR5cGUi 540 | IDogImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI2ludGVnZXIi 541 | LAogICAgICAiQHZhbHVlIiA6ICIzNCIKICAgIH0gXSwKICAgICJodHRwOi8v 542 | ZGJwZWRpYS5vcmcvcHJvcGVydHkvZmlsZW5hbWUiIDogWyB7CiAgICAgICJA 543 | bGFuZ3VhZ2UiIDogImVuIiwKICAgICAgIkB2YWx1ZSIgOiAiRGF2aWQgQm93 544 | aWUgLSBIZXJvZXMub2dnIgogICAgfSBdLAogICAgImh0dHA6Ly9kYnBlZGlh 545 | Lm9yZy9wcm9wZXJ0eS9sZWFkZXIiIDogWyB7CiAgICAgICJAbGFuZ3VhZ2Ui 546 | IDogImVuIiwKICAgICAgIkB2YWx1ZSIgOiAiTWljaGFlbCBNw7xsbGVyIE1p 547 | Y2hhZWwgTcO8bGxlciIKICAgIH0gXSwKICAgICJodHRwOi8vZGJwZWRpYS5v 548 | cmcvcHJvcGVydHkvbGVhZGVyVGl0bGUiIDogWyB7CiAgICAgICJAaWQiIDog 549 | Imh0dHA6Ly9kYnBlZGlhLm9yZy9yZXNvdXJjZS9Hb3Zlcm5pbmdfTWF5b3Jf 550 | b2ZfQmVybGluIgogICAgfSBdLAogICAgImh0dHA6Ly9kYnBlZGlhLm9yZy9w 551 | cm9wZXJ0eS9wbHoiIDogWyB7CiAgICAgICJAdHlwZSIgOiAiaHR0cDovL3d3 552 | dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjaW50ZWdlciIsCiAgICAgICJAdmFs 553 | dWUiIDogIjEwMTE1IgogICAgfSBdLAogICAgImh0dHA6Ly9kYnBlZGlhLm9y 554 | Zy9wcm9wZXJ0eS9wb3B1bGF0aW9uIiA6IFsgewogICAgICAiQHR5cGUiIDog 555 | Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI2ludGVnZXIiLAog 556 | ICAgICAiQHZhbHVlIiA6ICIzNTYyMTY2IgogICAgfSBdLAogICAgImh0dHA6 557 | Ly9kYnBlZGlhLm9yZy9wcm9wZXJ0eS9wb3B1bGF0aW9uRGVtb255bSIgOiBb 558 | IHsKICAgICAgIkBsYW5ndWFnZSIgOiAiZW4iLAogICAgICAiQHZhbHVlIiA6 559 | ICJCZXJsaW5lciIKICAgIH0gXSwKICAgICJodHRwOi8vZGJwZWRpYS5vcmcv 560 | cHJvcGVydHkvcnVsaW5nUGFydHkiIDogWyB7CiAgICAgICJAaWQiIDogImh0 561 | dHA6Ly9kYnBlZGlhLm9yZy9yZXNvdXJjZS9DaHJpc3RpYW5fRGVtb2NyYXRp 562 | Y19Vbmlvbl9vZl9HZXJtYW55IgogICAgfSwgewogICAgICAiQGlkIiA6ICJo 563 | dHRwOi8vZGJwZWRpYS5vcmcvcmVzb3VyY2UvU29jaWFsX0RlbW9jcmF0aWNf 564 | UGFydHlfb2ZfR2VybWFueSIKICAgIH0gXSwKICAgICJodHRwOi8vZGJwZWRp 565 | YS5vcmcvcHJvcGVydHkvdGl0bGUiIDogWyB7CiAgICAgICJAbGFuZ3VhZ2Ui 566 | IDogImVuIiwKICAgICAgIkB2YWx1ZSIgOiAiXCJIZXJvZXNcIiIKICAgIH0g 567 | XSwKICAgICJodHRwOi8vZGJwZWRpYS5vcmcvcHJvcGVydHkvdm9yd2FobCIg 568 | OiBbIHsKICAgICAgIkB0eXBlIiA6ICJodHRwOi8vd3d3LnczLm9yZy8yMDAx 569 | L1hNTFNjaGVtYSNpbnRlZ2VyIiwKICAgICAgIkB2YWx1ZSIgOiAiMzAiCiAg 570 | ICB9IF0sCiAgICAiaHR0cDovL3B1cmwub3JnL2RjL3Rlcm1zL3N1YmplY3Qi 571 | IDogWyB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9kYnBlZGlhLm9yZy9yZXNv 572 | dXJjZS9DYXRlZ29yeToxMjM3X2VzdGFibGlzaG1lbnRzIgogICAgfSwgewog 573 | ICAgICAiQGlkIiA6ICJodHRwOi8vZGJwZWRpYS5vcmcvcmVzb3VyY2UvQ2F0 574 | ZWdvcnk6QmVybGluIgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRwOi8v 575 | ZGJwZWRpYS5vcmcvcmVzb3VyY2UvQ2F0ZWdvcnk6Q2FwaXRhbHNfaW5fRXVy 576 | b3BlIgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRwOi8vZGJwZWRpYS5v 577 | cmcvcmVzb3VyY2UvQ2F0ZWdvcnk6Q2l0eS1zdGF0ZXMiCiAgICB9LCB7CiAg 578 | ICAgICJAaWQiIDogImh0dHA6Ly9kYnBlZGlhLm9yZy9yZXNvdXJjZS9DYXRl 579 | Z29yeTpHZXJtYW5fc3RhdGVfY2FwaXRhbHMiCiAgICB9LCB7CiAgICAgICJA 580 | aWQiIDogImh0dHA6Ly9kYnBlZGlhLm9yZy9yZXNvdXJjZS9DYXRlZ29yeTpN 581 | ZW1iZXJzX29mX3RoZV9IYW5zZWF0aWNfTGVhZ3VlIgogICAgfSwgewogICAg 582 | ICAiQGlkIiA6ICJodHRwOi8vZGJwZWRpYS5vcmcvcmVzb3VyY2UvQ2F0ZWdv 583 | cnk6UG9wdWxhdGVkX3BsYWNlc19lc3RhYmxpc2hlZF9pbl90aGVfMTN0aF9j 584 | ZW50dXJ5IgogICAgfSBdLAogICAgImh0dHA6Ly93d3cuZ2VvcnNzLm9yZy9n 585 | ZW9yc3MvcG9pbnQiIDogWyB7CiAgICAgICJAdmFsdWUiIDogIjUyLjUxNjY2 586 | NjY2NjY2NjY2NiAxMy4zODMzMzMzMzMzMzMzMzMiCiAgICB9IF0sCiAgICAi 587 | aHR0cDovL3d3dy53My5vcmcvMjAwMC8wMS9yZGYtc2NoZW1hI2NvbW1lbnQi 588 | IDogWyB7CiAgICAgICJAbGFuZ3VhZ2UiIDogImFyIiwKICAgICAgIkB2YWx1 589 | ZSIgOiAi2KjYsdmE2YrZhiAo2KPZhNmF2KfZhtmK2Kk6IEJlcmxpbikg2YfZ 590 | iiDYudin2LXZhdipINis2YXZh9mI2LHZitipINij2YTZhdin2YbZitinINin 591 | 2YTYp9iq2K3Yp9iv2YrYqdiMINmI2KXYrdiv2Ykg2YjZhNin2YrYp9iqINij 592 | 2YTZhdin2YbZitinINin2YTYs9iqINi52LTYsdip2Iwg2YPZhdinINij2YbZ 593 | h9inINij2YPYqNixINmF2K/ZhiDYo9mE2YXYp9mG2YrYpyDZhdmGINit2YrY 594 | qyDYudiv2K8g2KfZhNiz2YPYp9mGLiDZiNiq2LnYqtio2LEg2KjYsdmE2YrZ 595 | hiDYpdit2K/ZiSBcItin2YTZiNmE2KfZitin2Kog2KfZhNmF2K/ZhlwiINin 596 | 2YTYq9mE2KfYqyDYqNis2YXZh9mI2LHZitipINij2YTZhdin2YbZitinINin 597 | 2YTYp9iq2K3Yp9iv2YrYqSAo2KXZhNmJINis2KfZhtioINio2LHZitmF2YYg 598 | 2YjZh9in2YXYqNmI2LHYuinYjCDZiNiq2KPYqtmKINmH2LDZhyDYp9mE2KrY 599 | s9mF2YrYqSDZhdmGINmD2YjZhiDYrdiv2YjYryDYp9mE2YXYr9mK2YbYqSDZ 600 | h9mKINmG2YHYs9mH2Kcg2K3Yr9mI2K8g2KfZhNmI2YTYp9mK2KkuINmI2KjY 601 | sdmE2YrZhiDZh9mKINij2YrYttin2Ysg2KvYp9mG2Yog2KPZg9io2LEg2YXY 602 | r9mGINin2YTYp9iq2K3Yp9ivINin2YTYo9mI2LHZiNio2Yog2KjYudivINin 603 | 2YTYudin2LXZhdipINin2YTYqNix2YrYt9in2YbZitipINmE2YbYr9mGLtmI 604 | 2K7ZhNin2YQg2YHYqtix2KnYp9mE2K3YsdioINin2YTYqNin2LHYr9ipINmI 605 | 2KrYrdiv2YrYr9in2Ysg2YHZiiDYudin2YUgMTk2MdiMINmC2KfZhdiqINit 606 | 2YPZiNmF2Kkg2KPZhNmF2KfZhtmK2Kcg2KfZhNi02LHZgtmK2Kkg2KjYqti0 607 | 2YrZitivINmF2Kcg2YPYp9mGINmK2LnYsdmBINio2YDYrNiv2KfYsSDYqNix 608 | 2YTZitmGLiIKICAgIH0sIHsKICAgICAgIkBsYW5ndWFnZSIgOiAiZGUiLAog 609 | ICAgICAiQHZhbHVlIiA6ICJCZXJsaW4gKFtiyZvJkMyvy4hsacuQbl0pIGlz 610 | dCBkaWUgQnVuZGVzaGF1cHRzdGFkdCBkZXIgQnVuZGVzcmVwdWJsaWsgRGV1 611 | dHNjaGxhbmQgdW5kIHp1Z2xlaWNoIGVpbmVzIGlocmVyIEzDpG5kZXIuIERp 612 | ZSBTdGFkdCBCZXJsaW4gaXN0IG1pdCBydW5kIDMsNSBNaWxsaW9uZW4gRWlu 613 | d29obmVybiBkaWUgYmV2w7Zsa2VydW5nc3JlaWNoc3RlIHVuZCBtaXQgODky 614 | IFF1YWRyYXRraWxvbWV0ZXJuIGRpZSBmbMOkY2hlbmdyw7bDn3RlIEdlbWVp 615 | bmRlIERldXRzY2hsYW5kcyBzb3dpZSBuYWNoIEVpbndvaG5lcm4gZGllIHp3 616 | ZWl0Z3LDtsOfdGUgZGVyIEV1cm9ww6Rpc2NoZW4gVW5pb24uIFNpZSBiaWxk 617 | ZXQgZGFzIFplbnRydW0gZGVyIE1ldHJvcG9scmVnaW9uIEJlcmxpbi9CcmFu 618 | ZGVuYnVyZyAoNiBNaWxsaW9uZW4gRWludy4pIHVuZCBkZXIgQWdnbG9tZXJh 619 | dGlvbiBCZXJsaW4gKDQsNCBNaWxsaW9uZW4gRWludy4pLiBEZXIgU3RhZHRz 620 | dGFhdCB1bnRlcnRlaWx0IHNpY2ggaW4genfDtmxmIEJlemlya2UuIE5lYmVu 621 | IGRlbiBGbMO8c3NlbiBTcHJlZSB1bmQgSGF2ZWwgYmVmaW5kZW4gc2ljaCBp 622 | bSBTdGFkdGdlYmlldCBrbGVpbmVyZSBGbGllw59nZXfDpHNzZXIgc293aWUg 623 | emFobHJlaWNoZSBTZWVuIHVuZCBXw6RsZGVyLiIKICAgIH0sIHsKICAgICAg 624 | IkBsYW5ndWFnZSIgOiAiZW4iLAogICAgICAiQHZhbHVlIiA6ICJCZXJsaW4g 625 | KC9iyZlyy4hsyapuLywgW2LJm8mQzK/LiGxpy5BuXSkgaXMgdGhlIGNhcGl0 626 | YWwgb2YgR2VybWFueSBhbmQgb25lIG9mIHRoZSAxNiBzdGF0ZXMgb2YgR2Vy 627 | bWFueS4gV2l0aCBhIHBvcHVsYXRpb24gb2YgMy41IG1pbGxpb24gcGVvcGxl 628 | LCBpdCBpcyB0aGUgc2Vjb25kIG1vc3QgcG9wdWxvdXMgY2l0eSBwcm9wZXIg 629 | YW5kIHRoZSBzZXZlbnRoIG1vc3QgcG9wdWxvdXMgdXJiYW4gYXJlYSBpbiB0 630 | aGUgRXVyb3BlYW4gVW5pb24uIExvY2F0ZWQgaW4gbm9ydGhlYXN0ZXJuIEdl 631 | cm1hbnkgb24gdGhlIGJhbmtzIG9mIFJpdmVycyBTcHJlZSBhbmQgSGF2ZWws 632 | IGl0IGlzIHRoZSBjZW50cmUgb2YgdGhlIEJlcmxpbi1CcmFuZGVuYnVyZyBN 633 | ZXRyb3BvbGl0YW4gUmVnaW9uLCB3aGljaCBoYXMgYWJvdXQgc2l4IG1pbGxp 634 | b24gcmVzaWRlbnRzIGZyb20gb3ZlciAxODAgbmF0aW9ucy4gRHVlIHRvIGl0 635 | cyBsb2NhdGlvbiBpbiB0aGUgRXVyb3BlYW4gUGxhaW4sIEJlcmxpbiBpcyBp 636 | bmZsdWVuY2VkIGJ5IGEgdGVtcGVyYXRlIHNlYXNvbmFsIGNsaW1hdGUuIEFy 637 | b3VuZCBvbmUtdGhpcmQgb2YgdGhlIGNpdHkncyBhcmVhIGlzIGNvbXBvc2Vk 638 | IG9mIGZvcmVzdHMsIHBhcmtzLCBnYXJkZW5zLCByaXZlcnMgYW5kIGxha2Vz 639 | LiIKICAgIH0sIHsKICAgICAgIkBsYW5ndWFnZSIgOiAiZXMiLAogICAgICAi 640 | QHZhbHVlIiA6ICJCZXJsw61uIChCZXJsaW4gZW4gYWxlbcOhbiAoQWNlcmNh 641 | IGRlIGVzdGUgc29uaWRvIFtiyZvJkMyvy4hsacuQbl0gKSkgZXMgbGEgY2Fw 642 | aXRhbCBkZSBBbGVtYW5pYSB5IHVubyBkZSBsb3MgZGllY2lzw6lpcyBlc3Rh 643 | ZG9zIGZlZGVyYWRvcyBhbGVtYW5lcy4gU2UgbG9jYWxpemEgYWwgbm9yZXN0 644 | ZSBkZSBBbGVtYW5pYSwgYSBlc2Nhc29zIDcwIGttIGRlIGxhIGZyb250ZXJh 645 | IGNvbiBQb2xvbmlhLiBQb3IgbGEgY2l1ZGFkIGZsdXllbiBsb3MgcsOtb3Mg 646 | U3ByZWUsIEhhdmVsLCBQYW5rZSwgRGFobWUgeSBXdWhsZS4gQ29uIHVuYSBw 647 | b2JsYWNpw7NuIGRlIDMsNCBtaWxsb25lcyBkZSBoYWJpdGFudGVzLCBCZXJs 648 | w61uIGVzIGxhIGNpdWRhZCBtw6FzIHBvYmxhZGEgZGVsIHBhw61zLCBhc8Ot 649 | IGNvbW8gbGEgc2VndW5kYSBjaXVkYWQgZW4gdGFtYcOxbyB5IGxhIHF1aW50 650 | YSBhZ2xvbWVyYWNpw7NuIHVyYmFuYSBlbnRyZSBsb3MgcGHDrXNlcyBkZSBs 651 | YSBVbmnDs24gRXVyb3BlYS4iCiAgICB9LCB7CiAgICAgICJAbGFuZ3VhZ2Ui 652 | IDogImZyIiwKICAgICAgIkB2YWx1ZSIgOiAiQmVybGluIChwcm9ub25jw6kg 653 | W2LJm8qBLmzJm8yDXSA7IGVuIGFsbGVtYW5kIEJlcmxpbiBbYsmbyZDMry7L 654 | iGxpy5BuXSApIGVzdCBsYSBjYXBpdGFsZSBldCBsYSBwbHVzIGdyYW5kZSB2 655 | aWxsZSBkJ0FsbGVtYWduZS5TaXR1w6llIGRhbnMgbGUgbm9yZC1lc3QgZHUg 656 | cGF5cywgZWxsZSBmb3JtZSB1biBsYW5kICjDiXRhdCBmw6lkw6lyw6kpIMOg 657 | IHBhcnQgZW50acOocmUgZXQgY29tcHRlIGVudmlyb24gMyw1IG1pbGxpb25z 658 | IGQnaGFiaXRhbnRzLiBTZXMgaGFiaXRhbnRzIHMnYXBwZWxsZW50IGxlcyBC 659 | ZXJsaW5vaXMuIEJlcmxpbiBlc3QgbGEgZGV1eGnDqG1lIHZpbGxlIGV0IGxh 660 | IHNlcHRpw6htZSBhZ2dsb23DqXJhdGlvbiBsYSBwbHVzIHBldXBsw6llIGRl 661 | IGwnVW5pb24gZXVyb3DDqWVubmUuIEwnYWdnbG9tw6lyYXRpb24gZGUgQmVy 662 | bGluIHMnw6l0ZW5kIHN1ciAzIDczNCBrbTIgZXQgY29tcHRlIDQsNCBtaWxs 663 | aW9ucyBkJ2hhYml0YW50cywgZXQgbGEgcsOpZ2lvbiBtw6l0cm9wb2xpdGFp 664 | bmUgZGUgQmVybGluLUJyYW5kZWJvdXJnIHF1aSBjdW11bGUgbGVzIEzDpG5k 665 | ZXIgZGUgQmVybGluIGV0IGRlIEJyYW5kZWJvdXJnIHJlZ3JvdXBlIGF1IHRv 666 | dGFsIHByw6hzIGRlIDYgbWlsbGlvbnMgZCdoYWJpdGFudHMuIgogICAgfSwg 667 | ewogICAgICAiQGxhbmd1YWdlIiA6ICJpdCIsCiAgICAgICJAdmFsdWUiIDog 668 | IkJlcmxpbm8gKGluIHRlZGVzY286IEJlcmxpbiwgL2LJm8mQzKogy4hsacuQ 669 | bi8sICkgw6ggbGEgbWFnZ2lvcmUgY2l0dMOgIGUgbmVsIGNvbnRlbXBvIHVu 670 | IEJ1bmRlc2xhbmQgZGVsbGEgR2VybWFuaWEsIHF1aW5kaSB1bmEgY2l0dMOg 671 | LXN0YXRvLiBDYXBpdGFsZSBmZWRlcmFsZSBkZWxsYSBSZXB1YmJsaWNhIEZl 672 | ZGVyYWxlIGRpIEdlcm1hbmlhIGUgc2VkZSBkZWwgc3VvIGdvdmVybm8sIMOo 673 | IHVubyBkZWkgcGnDuSBpbXBvcnRhbnRpIGNlbnRyaSBwb2xpdGljaSwgY3Vs 674 | dHVyYWxpLCBzY2llbnRpZmljaSwgZmllcmlzdGljaSBlIG1lZGlhdGljaSBk 675 | J0V1cm9wYSBlLCBkb3BvIExvbmRyYSwgaWwgc2Vjb25kbyBjb211bmUgcGnD 676 | uSBwb3BvbG9zbyBkZWxsJ1VuaW9uZSBldXJvcGVhLCBjb24gMyA1MzEgMjAx 677 | IGFiaXRhbnRpLiBMJ2FyZWEgbWV0cm9wb2xpdGFuYSBoYSB1bmEgc3VwZXJm 678 | aWNpZSBjb21wbGVzc2l2YSBkaSAyIDg1MSBrbcKyIGVkIHVuYSBwb3BvbGF6 679 | aW9uZSBkaSA0IDQ2MiAxNjYgYWJpdGFudGksIG1lbnRyZSBsYSByZWdpb25l 680 | IG1ldHJvcG9saXRhbmEgZGkgQmVybGlubyBlIEJyYW5kZWJ1cmdvIGhhIHVu 681 | YSBzdXBlcmZpY2llIGRpIDMwIDM3MCBrbcKyIGVkIHVuYSBwb3BvbGF6aW9u 682 | ZSBkaSA2IDAyNCAwMDAgYWJpdGFudGkuIgogICAgfSwgewogICAgICAiQGxh 683 | bmd1YWdlIiA6ICJqYSIsCiAgICAgICJAdmFsdWUiIDogIuODmeODq+ODquOD 684 | s++8iOeLrDogQmVybGluIFtiyZvJkMyvy4hsacuQbl3jgIHkvK/mnpfvvInj 685 | ga/jgIHjg4njgqTjg4Tjga7pg73luILjgaflkIzlm73jga7pppbpg73jgafj 686 | gYLjgovjgIIxNuOBguOCi+mAo+mCpuW3nuOBruOBhuOBoeOBruS4gOOBpOOB 687 | p+OAgeW4guWfn+S6uuWPo+OBrzM1MOS4h+S6uuOBqOODieOCpOODhOOBp+OB 688 | r+acgOWkp+OBrumDveW4guOBp+asp+W3numAo+WQiOOBruW4guWfn+S6uuWP 689 | o+OBp+OBr+ODreODs+ODieODs+OBq+asoeOBhOOBpzLnlarnm67jgavlpJrj 690 | gY/jgIHpg73luILnmoTlnLDln5/jga7kurrlj6Pjga8355Wq55uu44Gr5aSa 691 | 44GE44CCIgogICAgfSwgewogICAgICAiQGxhbmd1YWdlIiA6ICJubCIsCiAg 692 | ICAgICJAdmFsdWUiIDogIkJlcmxpam4gKER1aXRzOiBCZXJsaW4pIGlzIGRl 693 | IGhvb2Zkc3RhZCB2YW4gRHVpdHNsYW5kIGVuIGFscyBzdGFkc3RhYXQgZWVu 694 | IGRlZWxzdGFhdCB2YW4gZGF0IGxhbmQuIE1ldCAzLjQzNy45MTYgaW53b25l 695 | cnMgaXMgQmVybGlqbiB0ZXZlbnMgZGUgZ3Jvb3RzdGUgc3RhZCB2YW4gaGV0 696 | IGxhbmQgZW4gZGUgb3Agw6nDqW4gbmEgZ3Jvb3RzdGUgc3RhZCBpbiBkZSBF 697 | dXJvcGVzZSBVbmllLiBEZSBzdGFkIGxpZ3QgaW4gaGV0IG5vb3Jkb29zdGVu 698 | IHZhbiBEdWl0c2xhbmQsIGFhbiBkZSByaXZpZXIgZGUgU3ByZWUgZW4gd29y 699 | ZHQgb21zbG90ZW4gZG9vciBkZSBkZWVsc3RhYXQgQnJhbmRlbmJ1cmcsIHdh 700 | YXJ2YW4gemUgc2luZHMgMTkyMCBnZWVuIGRlZWwgbWVlciB1aXRtYWFrdC4i 701 | CiAgICB9LCB7CiAgICAgICJAbGFuZ3VhZ2UiIDogInBsIiwKICAgICAgIkB2 702 | YWx1ZSIgOiAiQmVybGluIOKAkyBzdG9saWNhLCBzaWVkemliYSByesSFZHUg 703 | UmVwdWJsaWtpIEZlZGVyYWxuZWogTmllbWllYy4gTmFqd2nEmWtzemUgbWlh 704 | c3RvIE5pZW1pZWMsIG5hIHByYXdhY2gga3JhanUgendpxIV6a293ZWdvLiBa 705 | YWptdWplIHBvd2llcnpjaG5pxJkgb2suIDg5MiBrbcKyLCB6YW1pZXN6a3Vq 706 | ZSBqZSAzLDQgbWxuIG9zw7NiLiBKZXN0IHRyemVjaW0gbmFqd2nEmWtzenlt 707 | IChwbyBMb25keW5pZSBpIFBhcnnFvHUpIG1pYXN0ZW0gdyBVbmlpIEV1cm9w 708 | ZWpza2llai5CZXJsaW4gamVzdCBwb2R6aWVsb255IG5hIGR3YW5hxZtjaWUg 709 | b2tyxJlnw7N3IGFkbWluaXN0cmFjeWpueWNoIChCZXppcmspLiBQcnpleiBw 710 | cnplc3RyemXFhCBtaWVqc2vEhSBwcnplcMWCeXdhasSFIG0uaW4uIHJ6ZWtp 711 | IFNwcmV3YSBpIEhhd2VsYSwgYSBwb25hZHRvIHpuYWpkdWplIHNpxJkgd2ll 712 | bGUgamV6aW9yIGkgemF0b2ssIHcgdHltIG5handpxJlrc3plIE3DvGdnZWxz 713 | ZWUuIgogICAgfSwgewogICAgICAiQGxhbmd1YWdlIiA6ICJwdCIsCiAgICAg 714 | ICJAdmFsdWUiIDogIkJlcmxpbSAoZW0gYWxlbcOjbyBCZXJsaW4pIMOpIGEg 715 | Y2FwaXRhbCBlIHVtIGRvcyBkZXplc3NlaXMgZXN0YWRvcyBkYSBBbGVtYW5o 716 | YS4gQ29tIHVtYSBwb3B1bGHDp8OjbyBkZSAzLDUgbWlsaMO1ZXMgZGVudHJv 717 | IGRlIGxpbWl0ZXMgZGEgY2lkYWRlLCDDqSBhIG1haW9yIGNpZGFkZSBkbyBw 718 | YcOtcywgYWzDqW0gZGUgc2VyIGEgc2VndW5kYSBtYWlzIHBvcHVsb3NhIGUg 719 | YSBzw6l0aW1hIMOhcmVhIHVyYmFuYSBtYWlzIHBvdm9hZGEgZGEgVW5pw6Nv 720 | IEV1cm9wZWlhLiBTaXR1YWRhIG5vIG5vcmRlc3RlIGRhIEFsZW1hbmhhLCDD 721 | qSBvIGNlbnRybyBkYSDDoXJlYSBtZXRyb3BvbGl0YW5hIGRlIEJlcmxpbS1C 722 | cmFuZGVtYnVyZ28sIHF1ZSBpbmNsdWkgNSBtaWxow7VlcyBkZSBwZXNzb2Fz 723 | IGRlIG1haXMgZGUgMTkwIG5hw6fDtWVzLiBMb2NhbGl6YWRhIG5hIGdyYW5k 724 | ZSBwbGFuw61jaWUgZXVyb3BlaWEsIEJlcmxpbSDDqSBpbmZsdWVuY2lhZGEg 725 | cG9yIHVtIGNsaW1hIHRlbXBlcmFkbyBzYXpvbmFsLiBDZXJjYSBkZSB1bSB0 726 | ZXLDp28gZGEgw6FyZWEgZGEgY2lkYWRlIMOpIGNvbXBvc3RhIHBvciBmbG9y 727 | ZXN0YXMsIHBhcnF1ZXMsIGphcmRpbnMsIHJpb3MgZSBsYWdvcy4iCiAgICB9 728 | IF0sCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC8wMS9yZGYtc2NoZW1h 729 | I2xhYmVsIiA6IFsgewogICAgICAiQGxhbmd1YWdlIiA6ICJhciIsCiAgICAg 730 | ICJAdmFsdWUiIDogItio2LHZhNmK2YYiCiAgICB9LCB7CiAgICAgICJAbGFu 731 | Z3VhZ2UiIDogImRlIiwKICAgICAgIkB2YWx1ZSIgOiAiQmVybGluIgogICAg 732 | fSwgewogICAgICAiQGxhbmd1YWdlIiA6ICJlbiIsCiAgICAgICJAdmFsdWUi 733 | IDogIkJlcmxpbiIKICAgIH0sIHsKICAgICAgIkBsYW5ndWFnZSIgOiAiZXMi 734 | LAogICAgICAiQHZhbHVlIiA6ICJCZXJsw61uIgogICAgfSwgewogICAgICAi 735 | QGxhbmd1YWdlIiA6ICJmciIsCiAgICAgICJAdmFsdWUiIDogIkJlcmxpbiIK 736 | ICAgIH0sIHsKICAgICAgIkBsYW5ndWFnZSIgOiAiaXQiLAogICAgICAiQHZh 737 | bHVlIiA6ICJCZXJsaW5vIgogICAgfSwgewogICAgICAiQGxhbmd1YWdlIiA6 738 | ICJqYSIsCiAgICAgICJAdmFsdWUiIDogIuODmeODq+ODquODsyIKICAgIH0s 739 | IHsKICAgICAgIkBsYW5ndWFnZSIgOiAibmwiLAogICAgICAiQHZhbHVlIiA6 740 | ICJCZXJsaWpuIgogICAgfSwgewogICAgICAiQGxhbmd1YWdlIiA6ICJwbCIs 741 | CiAgICAgICJAdmFsdWUiIDogIkJlcmxpbiIKICAgIH0sIHsKICAgICAgIkBs 742 | YW5ndWFnZSIgOiAicHQiLAogICAgICAiQHZhbHVlIiA6ICJCZXJsaW0iCiAg 743 | ICB9LCB7CiAgICAgICJAbGFuZ3VhZ2UiIDogInJ1IiwKICAgICAgIkB2YWx1 744 | ZSIgOiAi0JHQtdGA0LvQuNC9IgogICAgfSwgewogICAgICAiQGxhbmd1YWdl 745 | IiA6ICJ6aCIsCiAgICAgICJAdmFsdWUiIDogIuafj+aelyIKICAgIH0gXSwK 746 | ICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzAxL3JkZi1zY2hlbWEjc2Vl 747 | QWxzbyIgOiBbIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2RicGVkaWEub3Jn 748 | L3Jlc291cmNlLzE5MjBzX0JlcmxpbiIKICAgIH0sIHsKICAgICAgIkBpZCIg 749 | OiAiaHR0cDovL2RicGVkaWEub3JnL3Jlc291cmNlL0JlcmxpbiIKICAgIH0s 750 | IHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2RicGVkaWEub3JnL3Jlc291cmNl 751 | L0dhbGxlcnkiCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9kYnBl 752 | ZGlhLm9yZy9yZXNvdXJjZS9HZXJtYW5fY3Vpc2luZSIKICAgIH0sIHsKICAg 753 | ICAgIkBpZCIgOiAiaHR0cDovL2RicGVkaWEub3JnL3Jlc291cmNlL0dlcm1h 754 | bnkiCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9kYnBlZGlhLm9y 755 | Zy9yZXNvdXJjZS9MaXN0X29mX211c2V1bXMiCiAgICB9LCB7CiAgICAgICJA 756 | aWQiIDogImh0dHA6Ly9kYnBlZGlhLm9yZy9yZXNvdXJjZS9MaXN0X29mX3Np 757 | Z2h0cyIKICAgIH0sIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2RicGVkaWEu 758 | b3JnL3Jlc291cmNlL0xpc3RzX29mX3R3aW5fdG93bnNfYW5kX3Npc3Rlcl9j 759 | aXRpZXMiCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9kYnBlZGlh 760 | Lm9yZy9yZXNvdXJjZS9Ud2luX3Rvd25zX2FuZF9zaXN0ZXJfY2l0aWVzIgog 761 | ICAgfSBdLAogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDIvMDcvb3dsI3Nh 762 | bWVBcyIgOiBbIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2NzLmRicGVkaWEu 763 | b3JnL3Jlc291cmNlL0JlcmzDrW4iCiAgICB9LCB7CiAgICAgICJAaWQiIDog 764 | Imh0dHA6Ly9kYXRhLm55dGltZXMuY29tLzE2MDU3NDI5NzI4MDg4NTczMzYx 765 | IgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRwOi8vZGF0YS5ueXRpbWVz 766 | LmNvbS9ONTA5ODcxODY4MzUyMjMwMzIzODEiCiAgICB9LCB7CiAgICAgICJA 767 | aWQiIDogImh0dHA6Ly9kYnBlZGlhLm9yZy9yZXNvdXJjZS9CZXJsaW4iCiAg 768 | ICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9kZS5kYnBlZGlhLm9yZy9y 769 | ZXNvdXJjZS9CZXJsaW4iCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6 770 | Ly9lbC5kYnBlZGlhLm9yZy9yZXNvdXJjZS/Oks61z4HOv867zq/Ovc6/Igog 771 | ICAgfSwgewogICAgICAiQGlkIiA6ICJodHRwOi8vZXMuZGJwZWRpYS5vcmcv 772 | cmVzb3VyY2UvQmVybMOtbiIKICAgIH0sIHsKICAgICAgIkBpZCIgOiAiaHR0 773 | cDovL2V1LmRicGVkaWEub3JnL3Jlc291cmNlL0JlcmxpbiIKICAgIH0sIHsK 774 | ICAgICAgIkBpZCIgOiAiaHR0cDovL2ZyLmRicGVkaWEub3JnL3Jlc291cmNl 775 | L0JlcmxpbiIKICAgIH0sIHsKICAgICAgIkBpZCIgOiAiaHR0cDovL2dhZG0u 776 | Z2Vvdm9jYWIub3JnL2lkLzNfMjI5NzYiCiAgICB9LCB7CiAgICAgICJAaWQi 777 | IDogImh0dHA6Ly9pZC5kYnBlZGlhLm9yZy9yZXNvdXJjZS9CZXJsaW4iCiAg 778 | ICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9pdC5kYnBlZGlhLm9yZy9y 779 | ZXNvdXJjZS9CZXJsaW5vIgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRw 780 | Oi8vamEuZGJwZWRpYS5vcmcvcmVzb3VyY2Uv44OZ44Or44Oq44OzIgogICAg 781 | fSwgewogICAgICAiQGlkIiA6ICJodHRwOi8va28uZGJwZWRpYS5vcmcvcmVz 782 | b3VyY2Uv67Kg66W866awIgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRw 783 | Oi8vbGlua2VkLXdlYi1hcGlzLmZpdC5jdnV0LmN6L3Jlc291cmNlL2Jlcmxp 784 | bl9jaXR5IgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRwOi8vbGlua2Vk 785 | Z2VvZGF0YS5vcmcvdHJpcGxpZnkvbm9kZTI0MDEwOTE4OSIKICAgIH0sIHsK 786 | ICAgICAgIkBpZCIgOiAiaHR0cDovL25sLmRicGVkaWEub3JnL3Jlc291cmNl 787 | L0Jlcmxpam4iCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9wbC5k 788 | YnBlZGlhLm9yZy9yZXNvdXJjZS9CZXJsaW4iCiAgICB9LCB7CiAgICAgICJA 789 | aWQiIDogImh0dHA6Ly9wdC5kYnBlZGlhLm9yZy9yZXNvdXJjZS9CZXJsaW0i 790 | CiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9yZGYuZnJlZWJhc2Uu 791 | Y29tL25zL20uMDE1NnEiCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6 792 | Ly9zdy5jeWMuY29tL2NvbmNlcHQvTXg0cnZWanJocHdwRWJHZHJjTjVZMjl5 793 | Y0EiCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9zd3MuZ2VvbmFt 794 | ZXMub3JnLzI5NTAxNTcvIgogICAgfSwgewogICAgICAiQGlkIiA6ICJodHRw 795 | Oi8vc3dzLmdlb25hbWVzLm9yZy8yOTUwMTU5LyIKICAgIH0sIHsKICAgICAg 796 | IkBpZCIgOiAiaHR0cDovL3N3cy5nZW9uYW1lcy5vcmcvNjU0NzM4My8iCiAg 797 | ICB9LCB7CiAgICAgICJAaWQiIDogImh0dHA6Ly93aWtpZGF0YS5kYnBlZGlh 798 | Lm9yZy9yZXNvdXJjZS9RNjQiCiAgICB9LCB7CiAgICAgICJAaWQiIDogImh0 799 | dHA6Ly93d3cud2lraWRhdGEub3JnL2VudGl0eS9RNjQiCiAgICB9LCB7CiAg 800 | ICAgICJAaWQiIDogImh0dHA6Ly93d3c0Lndpd2lzcy5mdS1iZXJsaW4uZGUv 801 | ZXVyb3N0YXQvcmVzb3VyY2UvcmVnaW9ucy9CZXJsaW4iCiAgICB9LCB7CiAg 802 | ICAgICJAaWQiIDogImh0dHA6Ly95YWdvLWtub3dsZWRnZS5vcmcvcmVzb3Vy 803 | Y2UvQmVybGluIgogICAgfSBdLAogICAgImh0dHA6Ly93d3cudzMub3JnLzIw 804 | MDMvMDEvZ2VvL3dnczg0X3BvcyNnZW9tZXRyeSIgOiBbIHsKICAgICAgIkB0 805 | eXBlIiA6ICJodHRwOi8vd3d3Lm9wZW5saW5rc3cuY29tL3NjaGVtYXMvdmly 806 | dHJkZiNHZW9tZXRyeSIsCiAgICAgICJAdmFsdWUiIDogIlBPSU5UKDEzLjM4 807 | MzMzMzIwNjE3NyA1Mi41MTY2NjY0MTIzNTQpIgogICAgfSBdLAogICAgImh0 808 | dHA6Ly93d3cudzMub3JnLzIwMDMvMDEvZ2VvL3dnczg0X3BvcyNsYXQiIDog 809 | WyB7CiAgICAgICJAdHlwZSIgOiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9Y 810 | TUxTY2hlbWEjZmxvYXQiLAogICAgICAiQHZhbHVlIiA6ICI1Mi41MTY3Igog 811 | ICAgfSBdLAogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDMvMDEvZ2VvL3dn 812 | czg0X3BvcyNsb25nIiA6IFsgewogICAgICAiQHR5cGUiIDogImh0dHA6Ly93 813 | d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI2Zsb2F0IiwKICAgICAgIkB2YWx1 814 | ZSIgOiAiMTMuMzgzMyIKICAgIH0gXSwKICAgICJodHRwOi8vd3d3LnczLm9y 815 | Zy9ucy9wcm92I3dhc0Rlcml2ZWRGcm9tIiA6IFsgewogICAgICAiQGlkIiA6 816 | ICJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jlcmxpbj9vbGRpZD03 817 | MDgxNjgzMDMiCiAgICB9IF0sCiAgICAiaHR0cDovL3htbG5zLmNvbS9mb2Fm 818 | LzAuMS9kZXBpY3Rpb24iIDogWyB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9j 819 | b21tb25zLndpa2ltZWRpYS5vcmcvd2lraS9TcGVjaWFsOkZpbGVQYXRoL0Nv 820 | YXRfb2ZfYXJtc19vZl9CZXJsaW4uc3ZnIgogICAgfSBdLAogICAgImh0dHA6 821 | Ly94bWxucy5jb20vZm9hZi8wLjEvaG9tZXBhZ2UiIDogWyB7CiAgICAgICJA 822 | aWQiIDogImh0dHA6Ly93d3cuYmVybGluLmRlL2VuLyIKICAgIH0gXSwKICAg 823 | ICJodHRwOi8veG1sbnMuY29tL2ZvYWYvMC4xL2lzUHJpbWFyeVRvcGljT2Yi 824 | IDogWyB7CiAgICAgICJAaWQiIDogImh0dHA6Ly9lbi53aWtpcGVkaWEub3Jn 825 | L3dpa2kvQmVybGluIgogICAgfSBdCiAgfSBdLAogICJAaWQiIDogImh0dHA6 826 | Ly9sb2NhbGhvc3Q6ODk4OC9tYXJtb3R0YS9jb250ZXh0L2NhY2hlIgp9IF0= 827 | http_version: 828 | recorded_at: Sat, 04 Feb 2017 04:22:13 GMT 829 | - request: 830 | method: delete 831 | uri: http://localhost:8988/marmotta/context/http://localhost:8988/linked-data-fragments-test 832 | body: 833 | encoding: US-ASCII 834 | string: '' 835 | headers: 836 | User-Agent: 837 | - Hurley v0.2 838 | Accept: 839 | - application/ld+json 840 | Content-Type: 841 | - application/ld+json 842 | Accept-Encoding: 843 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 844 | response: 845 | status: 846 | code: 200 847 | message: OK 848 | headers: 849 | Content-Length: 850 | - '0' 851 | body: 852 | encoding: UTF-8 853 | string: '' 854 | http_version: 855 | recorded_at: Sat, 04 Feb 2017 04:22:13 GMT 856 | recorded_with: VCR 3.0.3 857 | -------------------------------------------------------------------------------- /spec/cassettes/LinkedDataFragments_Marmotta/retrieve_a_subject_uri/should_retrieve_nothing_on_an_invalid_uri.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://localhost:8988/marmotta/resource?uri=http://dbpedia.org/resource/BerlinInvalidAndNotReal 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Hurley v0.2 12 | Accept: 13 | - application/ld+json 14 | Content-Type: 15 | - application/ld+json 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | response: 19 | status: 20 | code: 404 21 | message: Not Found 22 | headers: 23 | Accept: 24 | - application/ld+json 25 | Content-Type: 26 | - application/ld+json 27 | Content-Length: 28 | - '2478' 29 | body: 30 | encoding: UTF-8 31 | string: "\n\n\n\n \n \n 404 35 | Not Found - Marmotta Error\n \n \n \n \n \n \n\n \n\n
\n 41 | \
\n \n \"marmotta\n \n

Marmotta Error

\n 44 | \
\n
\n
\n 45 | \
\n
\n\n

Error: 46 | 404 Not Found

\n \n

\n http://dbpedia.org/resource/BerlinInvalidAndNotReal\"http://dbpedia.org/resource/BerlinInvalidAndNotReal\"\n

\n 50 | \ \n

\n Sorry, but the requested resource could 51 | not be found in Marmotta right now, but may be available again in the future. 52 | Further details in the logs.\n

\n \n
\n 53 | \ \n
\n\n
\n
\n 54 | \
\n \n Copyright 55 | © 2013-2014 The Apache Software Foundation\n \n
\n 56 | \
\n\n
\n\n \n\n \n\n\n" 58 | http_version: 59 | recorded_at: Sat, 04 Feb 2017 04:22:13 GMT 60 | - request: 61 | method: delete 62 | uri: http://localhost:8988/marmotta/context/http://localhost:8988/linked-data-fragments-test 63 | body: 64 | encoding: US-ASCII 65 | string: '' 66 | headers: 67 | User-Agent: 68 | - Hurley v0.2 69 | Accept: 70 | - application/ld+json 71 | Content-Type: 72 | - application/ld+json 73 | Accept-Encoding: 74 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 75 | response: 76 | status: 77 | code: 200 78 | message: OK 79 | headers: 80 | Content-Length: 81 | - '0' 82 | body: 83 | encoding: UTF-8 84 | string: '' 85 | http_version: 86 | recorded_at: Sat, 04 Feb 2017 04:22:13 GMT 87 | recorded_with: VCR 3.0.3 88 | -------------------------------------------------------------------------------- /spec/cassettes/LinkedDataFragments_Repository/behaves_like_a_backend/_retrieve/when_empty/raises_on_invalid_URL.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://example.com/moomin 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Accept: 11 | - text/turtle, text/rdf+turtle, application/turtle, application/x-turtle, application/ld+json, 12 | application/x-ld+json, application/n-triples, text/plain;q=0.5, application/n-quads, 13 | text/x-nquads, */*;q=0.1 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | User-Agent: 17 | - Ruby 18 | response: 19 | status: 20 | code: 404 21 | message: Not Found 22 | headers: 23 | Cache-Control: 24 | - max-age=604800 25 | Content-Type: 26 | - text/html 27 | Date: 28 | - Sat, 04 Feb 2017 04:24:17 GMT 29 | Etag: 30 | - '"359670651+gzip"' 31 | Expires: 32 | - Sat, 11 Feb 2017 04:24:17 GMT 33 | Last-Modified: 34 | - Fri, 09 Aug 2013 23:54:35 GMT 35 | Server: 36 | - ECS (oxr/83C7) 37 | Vary: 38 | - Accept-Encoding 39 | X-Cache: 40 | - HIT 41 | X-Ec-Custom-Error: 42 | - '1' 43 | Content-Length: 44 | - '606' 45 | body: 46 | encoding: ASCII-8BIT 47 | string: "\n\n\n Example Domain\n\n 48 | \ \n \n \n \n\n\n\n
\n

Example Domain

\n 60 | \

This domain is established to be used for illustrative examples in 61 | documents. You may use this\n domain in examples without prior coordination 62 | or asking for permission.

\n

More 63 | information...

\n
\n\n\n" 64 | http_version: 65 | recorded_at: Sat, 04 Feb 2017 04:22:38 GMT 66 | recorded_with: VCR 3.0.3 67 | -------------------------------------------------------------------------------- /spec/cassettes/LinkedDataFragments_Repository/retrieve_a_subject_uri/should_retrieve_nothing_on_an_invalid_uri.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://dbpedia.org/resource/BerlinInvalidAndNotReal 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Accept: 11 | - text/turtle, text/rdf+turtle, application/turtle, application/x-turtle, application/ld+json, 12 | application/x-ld+json, application/n-triples, text/plain;q=0.5, application/n-quads, 13 | text/x-nquads, */*;q=0.1 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | User-Agent: 17 | - Ruby 18 | response: 19 | status: 20 | code: 303 21 | message: See Other 22 | headers: 23 | Date: 24 | - Sat, 04 Feb 2017 04:24:31 GMT 25 | Content-Type: 26 | - text/turtle; qs=0.7 27 | Content-Length: 28 | - '0' 29 | Connection: 30 | - keep-alive 31 | Server: 32 | - Virtuoso/07.20.3217 (Linux) i686-generic-linux-glibc212-64 VDB 33 | Tcn: 34 | - choice 35 | Vary: 36 | - negotiate,accept 37 | Alternates: 38 | - '{"/data/BerlinInvalidAndNotReal.atom" 0.500000 {type application/atom+xml}}, 39 | {"/data/BerlinInvalidAndNotReal.jrdf" 0.600000 {type application/rdf+json}}, 40 | {"/data/BerlinInvalidAndNotReal.jsod" 0.500000 {type application/odata+json}}, 41 | {"/data/BerlinInvalidAndNotReal.json" 0.600000 {type application/json}}, {"/data/BerlinInvalidAndNotReal.jsonld" 42 | 0.500000 {type application/ld+json}}, {"/data/BerlinInvalidAndNotReal.n3" 43 | 0.800000 {type text/n3}}, {"/data/BerlinInvalidAndNotReal.nt" 0.800000 {type 44 | text/rdf+n3}}, {"/data/BerlinInvalidAndNotReal.ttl" 0.700000 {type text/turtle}}, 45 | {"/data/BerlinInvalidAndNotReal.xml" 0.950000 {type application/rdf+xml}}' 46 | Link: 47 | - ;rel="license",; 48 | rel="timegate" 49 | Location: 50 | - http://dbpedia.org/data/BerlinInvalidAndNotReal.ttl 51 | Expires: 52 | - Sat, 11 Feb 2017 04:24:31 GMT 53 | Cache-Control: 54 | - max-age=604800 55 | Access-Control-Allow-Origin: 56 | - "*" 57 | Access-Control-Allow-Credentials: 58 | - 'true' 59 | Access-Control-Allow-Methods: 60 | - GET, POST, OPTIONS 61 | Access-Control-Allow-Headers: 62 | - DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept-Encoding 63 | body: 64 | encoding: UTF-8 65 | string: '' 66 | http_version: 67 | recorded_at: Sat, 04 Feb 2017 04:22:51 GMT 68 | - request: 69 | method: get 70 | uri: http://dbpedia.org/data/BerlinInvalidAndNotReal.ttl 71 | body: 72 | encoding: US-ASCII 73 | string: '' 74 | headers: 75 | Accept: 76 | - text/turtle, text/rdf+turtle, application/turtle, application/x-turtle, application/ld+json, 77 | application/x-ld+json, application/n-triples, text/plain;q=0.5, application/n-quads, 78 | text/x-nquads, */*;q=0.1 79 | Accept-Encoding: 80 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 81 | User-Agent: 82 | - Ruby 83 | response: 84 | status: 85 | code: 200 86 | message: OK 87 | headers: 88 | Date: 89 | - Sat, 04 Feb 2017 04:24:31 GMT 90 | Content-Type: 91 | - text/turtle; charset=UTF-8 92 | Content-Length: 93 | - '15' 94 | Connection: 95 | - keep-alive 96 | Server: 97 | - Virtuoso/07.20.3217 (Linux) i686-generic-linux-glibc212-64 VDB 98 | Expires: 99 | - Sat, 11 Feb 2017 04:24:31 GMT 100 | Link: 101 | - ;rel="license",; 102 | rel="alternate"; type="application/rdf+xml"; title="Structured Descriptor 103 | Document (RDF/XML format)", ; 104 | rel="alternate"; type="text/n3"; title="Structured Descriptor Document (N3/Turtle 105 | format)", ; rel="alternate"; 106 | type="application/json"; title="Structured Descriptor Document (RDF/JSON format)", 107 | ; rel="alternate"; type="application/atom+xml"; 108 | title="OData (Atom+Feed format)", ; 109 | rel="alternate"; type="application/odata+json"; title="OData (JSON format)", 110 | ; rel="alternate"; type="text/html"; 111 | title="XHTML+RDFa", ; 112 | rel="http://xmlns.com/foaf/0.1/primaryTopic", ; 113 | rev="describedby", ; 114 | rel="timegate" 115 | X-Sparql-Default-Graph: 116 | - http://dbpedia.org 117 | Cache-Control: 118 | - max-age=604800 119 | Access-Control-Allow-Origin: 120 | - "*" 121 | Access-Control-Allow-Credentials: 122 | - 'true' 123 | Access-Control-Allow-Methods: 124 | - GET, POST, OPTIONS 125 | Access-Control-Allow-Headers: 126 | - DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept-Encoding 127 | Accept-Ranges: 128 | - bytes 129 | body: 130 | encoding: UTF-8 131 | string: "# Empty TURTLE\n" 132 | http_version: 133 | recorded_at: Sat, 04 Feb 2017 04:22:52 GMT 134 | recorded_with: VCR 3.0.3 135 | -------------------------------------------------------------------------------- /spec/controllers/dataset_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe DatasetController do 4 | describe "index" do 5 | 6 | context "JSON-LD" do 7 | before do 8 | get :index, :format => :jsonld 9 | end 10 | it "should return a graph" do 11 | expect(JSON::LD::Reader.new(response.body).statements.to_a.length).not_to eq 0 12 | end 13 | it "should be JSON-LD" do 14 | expect(response.content_type).to eq "application/ld+json" 15 | end 16 | end 17 | 18 | context "n-triples" do 19 | before do 20 | get :index, :format => :nt 21 | end 22 | it "should return a graph" do 23 | expect(RDF::NTriples::Reader.new(response.body).statements.to_a.length).not_to eq 0 24 | end 25 | it "should be n-triples" do 26 | expect(response.content_type).to eq "application/n-triples" 27 | end 28 | end 29 | 30 | context "ttl" do 31 | before do 32 | get :index, :format => :ttl 33 | end 34 | it "should return a graph" do 35 | expect(RDF::Turtle::Reader.new(response.body).statements.to_a.length).not_to eq 0 36 | end 37 | it "should be n-triples" do 38 | expect(response.content_type).to eq "text/turtle" 39 | end 40 | end 41 | 42 | context "invalid" do 43 | it "should be of type 404 Routing Error" do 44 | expect{get :index, :format => :invalid}.to raise_error(ActionController::RoutingError) 45 | end 46 | 47 | it "should output valid response formats" do 48 | expect{get :index, :format => :invalid}.to raise_error(ActionController::RoutingError, /[ttl].+[application\/ld\+json]/) 49 | end 50 | end 51 | 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /spec/controllers/subject_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe SubjectController do 4 | 5 | describe "settings" do 6 | #FIXME 7 | context "#cache_service" do 8 | it "should default be set to a valid service with a retrieve method" do 9 | expect(SubjectController.cache_service.respond_to?(:retrieve)).to eq true 10 | end 11 | end 12 | 13 | context "#routing" do 14 | it "should correctly return the subject route for various uri endpoints" do 15 | 16 | allow(Setting).to receive(:config).and_return({uri_endpoint: 'http://localhost:3000/{?subject}'}) 17 | expect(Setting.uri_endpoint_route).to eq '/*subject' 18 | 19 | allow(Setting).to receive(:config).and_return({uri_endpoint: 'http://localhost:3000/subject/{?subject}'}) 20 | expect(Setting.uri_endpoint_route).to eq '/subject/*subject' 21 | 22 | allow(Setting).to receive(:config).and_return({uri_endpoint: 'https://localhost:3000/long/a/{?subject}'}) 23 | expect(Setting.uri_endpoint_route).to eq '/long/a/*subject' 24 | 25 | allow(Setting).to receive(:config).and_return({uri_endpoint: 'https://www.example.com:8888/fds/a/{?subject}'}) 26 | expect(Setting.uri_endpoint_route).to eq '/fds/a/*subject' 27 | 28 | end 29 | 30 | it 'should error on an incorrect uri_endpoint setting' do 31 | #No http 32 | allow(Setting).to receive(:config).and_return({uri_endpoint: 'www.example.com:8888/fds/a/{?subject}'}) 33 | expect{Setting.uri_endpoint_route}.to raise_error(ArgumentError) 34 | 35 | #No ending slash 36 | allow(Setting).to receive(:config).and_return({uri_endpoint: 'http://localhost:3000{?subject}'}) 37 | expect{Setting.uri_endpoint_route}.to raise_error(ArgumentError) 38 | end 39 | end 40 | 41 | end 42 | 43 | describe "subject" do 44 | 45 | context "JSON-LD", :vcr do 46 | before do 47 | get :subject, {:subject => 'http://dbpedia.org/resource/Berlin',:format => :jsonld} 48 | end 49 | it "should return a graph" do 50 | expect(JSON::LD::Reader.new(response.body).statements.to_a.length).not_to eq 0 51 | end 52 | it "should be JSON-LD" do 53 | expect(response.content_type).to eq "application/ld+json" 54 | end 55 | end 56 | 57 | context "n-triples", :vcr do 58 | before do 59 | get :subject, {:subject => 'http://dbpedia.org/resource/Berlin', :format => :nt} #This breaks in Blazegraph? CHECKME 60 | end 61 | it "should return a graph" do 62 | expect(RDF::NTriples::Reader.new(response.body).statements.to_a.length).not_to eq 0 63 | end 64 | it "should be n-triples" do 65 | expect(response.content_type).to eq "application/n-triples" 66 | end 67 | end 68 | 69 | context "ttl", :vcr do 70 | before do 71 | get :subject, {:subject => 'http://dbpedia.org/resource/Berlin', :format => :ttl} 72 | end 73 | it "should return a graph" do 74 | expect(RDF::Turtle::Reader.new(response.body).statements.to_a.length).not_to eq 0 75 | end 76 | it "should be n-triples" do 77 | expect(response.content_type).to eq "text/turtle" 78 | end 79 | end 80 | 81 | context "invalid", :vcr do 82 | it "should be of type 404 Routing Error" do 83 | expect{get :subject, {:subject => 'http://dbpedia.org/resource/Berlin', :format => :invalid}}.to raise_error(ActionController::RoutingError) 84 | end 85 | 86 | it "should output valid response formats" do 87 | expect{get :subject, {:subject => 'http://dbpedia.org/resource/Berlin', :format => :invalid}}.to raise_error(ActionController::RoutingError, /[ttl].+[application\/ld\+json]/) 88 | end 89 | end 90 | 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/builders/control_builder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/builders' 4 | 5 | describe LinkedDataFragments::ControlBuilder do 6 | subject { described_class.new(control, property) } 7 | 8 | let(:control) { "subject" } 9 | let(:property) { RDF.subject } 10 | 11 | describe '#control' do 12 | it { expect(subject.control).to eq control } 13 | end 14 | 15 | describe '#property' do 16 | it { expect(subject.property).to eq property } 17 | end 18 | 19 | describe "#build" do 20 | let(:result) { subject.build } 21 | 22 | it "should return a control with a variable" do 23 | expect(result.variable).to contain_exactly control 24 | end 25 | 26 | it "should return a control with a property" do 27 | expect(result.property).to contain_exactly property 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/builders/dataset_builder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/builders' 4 | 5 | describe LinkedDataFragments::DatasetBuilder do 6 | subject { described_class.new(**opts) } 7 | 8 | let(:opts) { {} } 9 | 10 | describe '#build' do 11 | let(:result) { subject.build } 12 | 13 | it 'assigns uri endpoint' do 14 | expect(result.uri_lookup_endpoint) 15 | .to contain_exactly(subject.uri_endpoint.to_s) 16 | end 17 | 18 | it 'has the appropriate subject' do 19 | expect(result.rdf_subject).to eq RDF::URI(subject.uri_root) 20 | end 21 | 22 | it 'has a search endpoint with a template' do 23 | expect(result.search.first.template.first) 24 | .to eq subject.uri_endpoint.to_s 25 | end 26 | 27 | it 'has a search endpoint with mappings' do 28 | expect(result.search.first.mapping.first.property) 29 | .to contain_exactly(RDF.subject) 30 | end 31 | 32 | context 'with values' do 33 | let(:opts) do 34 | { uri_endpoint: template, uri_root: root, control_mapping: mapping } 35 | end 36 | 37 | let(:mapping) { { 'object' => RDF.object } } 38 | let(:root) { 'http://example.com/my_dataset/' } 39 | let(:template) { LinkedDataFragments::HydraTemplate.new( "#{root}{?object}") } 40 | 41 | it 'has the paramaterized endpoint' do 42 | expect(result.uri_lookup_endpoint).to contain_exactly template.to_s 43 | end 44 | 45 | it 'has the paramaterized subject' do 46 | expect(result.rdf_subject).to eq RDF::URI(root) 47 | end 48 | 49 | it 'has a search endpoint with the paramaterized template' do 50 | expect(result.search.first.template) 51 | .to contain_exactly(template.to_s) 52 | end 53 | 54 | it 'has a search endpoint with parameterized mappings' do 55 | expect(result.search.first.mapping.first.property) 56 | .to contain_exactly(RDF.object) 57 | end 58 | end 59 | end 60 | 61 | describe '#uri_endpoint' do 62 | it 'defaults to configured value' do 63 | expect(subject.uri_endpoint.to_s) 64 | .to eq LinkedDataFragments::Settings.uri_endpoint 65 | end 66 | 67 | it 'default manifests as HydraTemplate instance' do 68 | expect(subject.uri_endpoint) 69 | .to be_a LinkedDataFragments::HydraTemplate 70 | end 71 | end 72 | 73 | describe '#uri_root' do 74 | it 'defaults to the configured value' do 75 | expect(subject.uri_root).to eq LinkedDataFragments::Settings.uri_root 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/builders/template_builder_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/builders' 4 | 5 | describe LinkedDataFragments::TemplateBuilder do 6 | subject { described_class.new(node, template) } 7 | 8 | let(:node) { LinkedDataFragments::Dataset.new } 9 | let(:template) { 'http://localhost:4000/{?subject}' } 10 | 11 | describe '#build' do 12 | it 'builds a template with the node as parent' do 13 | expect(subject.build.parent).to eql node 14 | end 15 | 16 | it 'sets #template to on built template' do 17 | expect(subject.build.template).to contain_exactly template 18 | end 19 | end 20 | 21 | describe '#dataset_node' do 22 | it { expect(subject.dataset_node).to eql node } 23 | end 24 | 25 | describe '#uri_template' do 26 | it { expect(subject.uri_template).to eql template } 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/hydra_template_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe LinkedDataFragments::HydraTemplate do 4 | subject { described_class.new(template) } 5 | let(:template) { 'http://localhost:4000/{?subject}' } 6 | 7 | describe '#controls' do 8 | it 'should return the mapped controls' do 9 | expect(subject.controls).to eq ['subject'] 10 | end 11 | 12 | context 'when given multiple controls' do 13 | let(:template) { 'http://localhost:4000/{?subject,predicate, object}' } 14 | 15 | it 'should return all of them' do 16 | expect(subject.controls).to eq ['subject', 'predicate', 'object'] 17 | end 18 | end 19 | 20 | context 'with no controls' do 21 | let(:template) { 'http://localhost:4000' } 22 | 23 | it 'should return an empty array' do 24 | expect(subject.controls).to be_empty 25 | end 26 | end 27 | 28 | context 'with slashes to separate controls' do 29 | let(:template) { 'http://localhost:4000/{subject}/{predicate}' } 30 | 31 | it 'should return them' do 32 | expect(subject.controls).to eq ['subject', 'predicate'] 33 | end 34 | end 35 | end 36 | 37 | describe '#to_s' do 38 | it 'should be the template' do 39 | expect(subject.to_s).to eql template 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/models/control_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/models' 4 | 5 | describe LinkedDataFragments::Control do 6 | subject { described_class.new } 7 | 8 | it 'should apply the control schema' do 9 | LinkedDataFragments::ControlSchema.properties.each do |property| 10 | expect(subject.class.properties[property.name.to_s].predicate) 11 | .to eq property.predicate 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/models/dataset_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/models' 4 | 5 | describe LinkedDataFragments::Dataset do 6 | subject { described_class.new(uri) } 7 | let(:uri) { 'http://localhost:3000#dataset' } 8 | 9 | describe '#type' do 10 | it 'should be a hydra collection' do 11 | expect(subject.type) 12 | .to include RDF::URI('http://www.w3.org/ns/hydra/core#Collection') 13 | end 14 | 15 | it 'should be a dataset' do 16 | expect(subject.type) 17 | .to include RDF::URI('http://rdfs.org/ns/void#Dataset') 18 | end 19 | end 20 | 21 | it 'should apply the dataset schema' do 22 | LinkedDataFragments::DatasetSchema.properties.each do |property| 23 | expect(subject.class.properties[property.name.to_s].predicate).to eq property.predicate 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/models/result_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/models' 4 | 5 | describe LinkedDataFragments::Result do 6 | subject { described_class.new(root_uri) } 7 | 8 | let(:root_uri) { 'http://localhost:3000' } 9 | 10 | describe '#rdf_subject' do 11 | it 'should be the passed URI' do 12 | expect(subject.rdf_subject).to eq RDF::URI(root_uri) 13 | end 14 | end 15 | 16 | describe '#type' do 17 | it "should be a hydra collection" do 18 | expect(subject.type) 19 | .to include RDF::URI('http://www.w3.org/ns/hydra/core#Collection') 20 | end 21 | 22 | it "should be a paged collection" do 23 | expect(subject.type) 24 | .to include RDF::URI('http://www.w3.org/ns/hydra/core#PagedCollection') 25 | end 26 | end 27 | 28 | it 'should apply the Result schema' do 29 | LinkedDataFragments::ResultSchema.properties.each do |property| 30 | expect(subject.class.properties[property.name.to_s].predicate) 31 | .to eq property.predicate 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/models/template_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/models' 4 | 5 | describe LinkedDataFragments::Template do 6 | subject { described_class.new(uri) } 7 | let(:uri) { RDF::Node.new('triplePattern') } 8 | 9 | it 'should apply the template schema' do 10 | LinkedDataFragments::TemplateSchema.properties.each do |property| 11 | expect(subject.class.properties[property.name.to_s].predicate) 12 | .to eq property.predicate 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/schemas/control_schema_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe LinkedDataFragments::ControlSchema do 4 | it_behaves_like 'a schema', [:variable, :property] 5 | end 6 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/schemas/dataset_schema_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe LinkedDataFragments::DatasetSchema do 4 | it_behaves_like 'a schema', [:subset, :uri_lookup_endpoint, :search, :member] 5 | end 6 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/schemas/result_schema_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe LinkedDataFragments::ResultSchema do 4 | it_behaves_like 'a schema', [:subset, 5 | :title, 6 | :description, 7 | :source, 8 | :triples_count, 9 | :total_items, 10 | :items_per_page, 11 | :first_page 12 | ] 13 | end 14 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/schemas/template_schema_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe LinkedDataFragments::TemplateSchema do 4 | it_behaves_like 'a schema', [:template, :mapping] 5 | end 6 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'linked_data_fragments/service' 4 | require 'linked_data_fragments/repository' 5 | 6 | describe LinkedDataFragments::Service do 7 | subject { described_class.instance } 8 | 9 | before do 10 | # @todo: REMOVE THIS HACKY STUB 11 | allow(LinkedDataFragments::Settings) 12 | .to receive(:cache_backend) 13 | .and_return(:repository) 14 | end 15 | 16 | describe '#cache' do 17 | it 'gives a backend' do 18 | expect(subject.cache).to respond_to :retrieve 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/linked_data_fragments/settings_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe LinkedDataFragments::Settings do 4 | describe '.app_root' do 5 | it 'gives a relative path string "." by default' 6 | it 'when called within a rails app gives Rails.root' 7 | it 'gives APP_ROOT when available' 8 | end 9 | 10 | describe '.config' do 11 | it 'loads the config file' 12 | end 13 | 14 | describe '.config_path' do 15 | it 'gives the config file path' do 16 | expect(described_class.config_path) 17 | .to eq "#{described_class.app_root}/config/ldf.yml" 18 | end 19 | end 20 | 21 | describe '.env' do 22 | it 'defaults to "development"' 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV['RAILS_ENV'] ||= 'test' 3 | require 'spec_helper' 4 | require File.expand_path('../../config/environment', __FILE__) 5 | require 'rspec/rails' 6 | # Add additional requires below this line. Rails is not loaded until this point! 7 | 8 | # Requires supporting ruby files with custom matchers and macros, etc, in 9 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are 10 | # run as spec files by default. This means that files in spec/support that end 11 | # in _spec.rb will both be required and run as specs, causing the specs to be 12 | # run twice. It is recommended that you do not name files matching this glob to 13 | # end with _spec.rb. You can configure this pattern with the --pattern 14 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. 15 | # 16 | # The following line is provided for convenience purposes. It has the downside 17 | # of increasing the boot-up time by auto-requiring all files in the support 18 | # directory. Alternatively, in the individual `*_spec.rb` files, manually 19 | # require only the support files necessary. 20 | # 21 | # Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 22 | 23 | # Checks for pending migrations before tests are run. 24 | # If you are not using ActiveRecord, you can remove this line. 25 | ActiveRecord::Migration.maintain_test_schema! 26 | 27 | RSpec.configure do |config| 28 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 29 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 30 | 31 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 32 | # examples within a transaction, remove the following line or assign false 33 | # instead of true. 34 | config.use_transactional_fixtures = true 35 | 36 | # RSpec Rails can automatically mix in different behaviours to your tests 37 | # based on their file location, for example enabling you to call `get` and 38 | # `post` in specs under `spec/controllers`. 39 | # 40 | # You can disable this behaviour by removing the line below, and instead 41 | # explicitly tag your specs with their type, e.g.: 42 | # 43 | # RSpec.describe UsersController, :type => :controller do 44 | # # ... 45 | # end 46 | # 47 | # The different available types are documented in the features, such as in 48 | # https://relishapp.com/rspec/rspec-rails/docs 49 | config.infer_spec_type_from_file_location! 50 | end 51 | -------------------------------------------------------------------------------- /spec/routing/root_routing_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "root routes" do 4 | it "should navigate to the dataset controller" do 5 | expect(get "/").to route_to :controller => "dataset", :action => "index" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/routing/subject_routing_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "subject routes" do 4 | it "should navigate to the subject controller on a single subject param" do 5 | expect(get "/http://dbpedia.org/resource/Berlin").to route_to :controller => "subject", :action => "subject", :subject=>"http://dbpedia.org/resource/Berlin" 6 | end 7 | it "should navigate to the subject controller even if it's a root URI" do 8 | expect(get "/http://dbpedia.org").to route_to :controller => "subject", :action => "subject", :subject => "http://dbpedia.org" 9 | end 10 | it "should navigate to the subject controller if a good format is provided" do 11 | expect(get "/http://dbpedia.org.ttl").to route_to :controller => "subject", :action => "subject", :subject => "http://dbpedia.org", :format => "ttl" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'vcr_setup' 2 | require 'linked_data_fragments' 3 | 4 | Dir['./spec/support/**/*.rb'].each { |f| require f } 5 | 6 | # This file was generated by the `rails generate rspec:install` command. Conventionally, all 7 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 8 | # The generated `.rspec` file contains `--require spec_helper` which will cause 9 | # this file to always be loaded, without a need to explicitly require it in any 10 | # files. 11 | # 12 | # Given that it is always loaded, you are encouraged to keep this file as 13 | # light-weight as possible. Requiring heavyweight dependencies from this file 14 | # will add to the boot time of your test suite on EVERY test run, even for an 15 | # individual file that may not need all of that loaded. Instead, consider making 16 | # a separate helper file that requires the additional dependencies and performs 17 | # the additional setup, and require it from the spec files that actually need 18 | # it. 19 | # 20 | # The `.rspec` file also contains a few flags that are not defaults but that 21 | # users commonly want. 22 | # 23 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 24 | RSpec.configure do |config| 25 | # rspec-expectations config goes here. You can use an alternate 26 | # assertion/expectation library such as wrong or the stdlib/minitest 27 | # assertions if you prefer. 28 | config.expect_with :rspec do |expectations| 29 | # This option will default to `true` in RSpec 4. It makes the `description` 30 | # and `failure_message` of custom matchers include text for helper methods 31 | # defined using `chain`, e.g.: 32 | # be_bigger_than(2).and_smaller_than(4).description 33 | # # => "be bigger than 2 and smaller than 4" 34 | # ...rather than: 35 | # # => "be bigger than 2" 36 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 37 | end 38 | 39 | # rspec-mocks config goes here. You can use an alternate test double 40 | # library (such as bogus or mocha) by changing the `mock_with` option here. 41 | config.mock_with :rspec do |mocks| 42 | # Prevents you from mocking or stubbing a method that does not exist on 43 | # a real object. This is generally recommended, and will default to 44 | # `true` in RSpec 4. 45 | mocks.verify_partial_doubles = true 46 | end 47 | 48 | config.before(:each) do 49 | # @todo: Eliminate this. 50 | if Object.const_defined?('Setting') 51 | allow(Setting).to receive(:cache_backend).and_return('repository') 52 | end 53 | end 54 | 55 | # The settings below are suggested to provide a good initial experience 56 | # with RSpec, but feel free to customize to your heart's content. 57 | =begin 58 | # These two settings work together to allow you to limit a spec run 59 | # to individual examples or groups you care about by tagging them with 60 | # `:focus` metadata. When nothing is tagged with `:focus`, all examples 61 | # get run. 62 | config.filter_run :focus 63 | config.run_all_when_everything_filtered = true 64 | 65 | # Limits the available syntax to the non-monkey patched syntax that is 66 | # recommended. For more details, see: 67 | # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax 68 | # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 69 | # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching 70 | config.disable_monkey_patching! 71 | 72 | # Many RSpec users commonly either run the entire suite or an individual 73 | # file, and it's useful to allow more verbose output when running an 74 | # individual spec file. 75 | if config.files_to_run.one? 76 | # Use the documentation formatter for detailed output, 77 | # unless a formatter has already been configured 78 | # (e.g. via a command-line flag). 79 | config.default_formatter = 'doc' 80 | end 81 | 82 | # Print the 10 slowest examples and example groups at the 83 | # end of the spec run, to help surface which specs are running 84 | # particularly slow. 85 | config.profile_examples = 10 86 | 87 | # Run specs in random order to surface order dependencies. If you find an 88 | # order dependency and want to debug it, you can fix the order by providing 89 | # the seed, which is printed after each run. 90 | # --seed 1234 91 | config.order = :random 92 | 93 | # Seed global randomization in this process using the `--seed` CLI option. 94 | # Setting this allows you to use `--seed` to deterministically reproduce 95 | # test failures related to randomization by passing the same `--seed` value 96 | # as the one that triggered the failure. 97 | Kernel.srand config.seed 98 | =end 99 | end 100 | -------------------------------------------------------------------------------- /spec/support/shared_examples/backend.rb: -------------------------------------------------------------------------------- 1 | shared_examples 'a backend' do 2 | let(:url) { 'http://dbpedia.org/resource/Berlin' } 3 | 4 | after { subject.delete_all! } 5 | 6 | describe '.for' do 7 | it 'defaults to Repostiory' do 8 | expect(described_class.for) 9 | .to be_a LinkedDataFragments::Repository 10 | end 11 | 12 | it 'raises ArgumentError when name does not exist' do 13 | expect { described_class.for(name: :totally_fake) } 14 | .to raise_error LinkedDataFragments::BackendBase::UnsupportedBackend 15 | end 16 | end 17 | 18 | describe '#add', :vcr do 19 | it 'adds a url' do 20 | expect { subject.add(url) } 21 | .to change { subject.has_resource?(url) }.from(false).to(true) 22 | end 23 | end 24 | 25 | describe '#cache_backend_context' do 26 | let(:context) { 'http://example.com/my_named_graph' } 27 | 28 | it 'has a backend context' do 29 | unless subject.cache_backend_context.nil? 30 | expect(subject.cache_backend_context).to be_a String 31 | end 32 | end 33 | 34 | it 'sets backend context' do 35 | expect { subject.cache_backend_context = context } 36 | .to change { subject.cache_backend_context }.to eq context 37 | end 38 | end 39 | 40 | describe '#cache_backend_url' do 41 | it 'has a backend url' do 42 | unless subject.cache_backend_url.nil? 43 | expect(subject.cache_backend_url).to be_a String 44 | end 45 | end 46 | 47 | it 'sets backend url' do 48 | expect { subject.cache_backend_url = url } 49 | .to change { subject.cache_backend_url }.to eq url 50 | end 51 | end 52 | 53 | describe '#delete_all!', :vcr do 54 | it 'removes resources' do 55 | subject.add(url) 56 | 57 | expect { subject.delete_all! } 58 | .to change { subject.has_resource?(url) }.from(true).to(false) 59 | end 60 | 61 | it 'empties backend' do 62 | subject.add(url) 63 | 64 | expect { subject.delete_all! } 65 | .to change { subject.empty? }.from(false).to(true) 66 | end 67 | end 68 | 69 | describe '#empty?', :vcr do 70 | it 'becomes non-empty when a resource is added' do 71 | expect { subject.add(url) } 72 | .to change { subject.empty? }.from(true).to(false) 73 | end 74 | end 75 | 76 | describe '#has?', :vcr do 77 | it 'has a resource that has been added' do 78 | subject.add(url) 79 | 80 | expect(subject).to have_resource url 81 | end 82 | end 83 | 84 | describe '#retrieve' do 85 | context 'when empty', :vcr do 86 | it 'loads a valid URL' do 87 | expect(subject.retrieve(url)).to respond_to :each_statement 88 | end 89 | 90 | it 'raises on invalid URL' do 91 | expect { subject.retrieve('http://example.com/moomin') } 92 | .to raise_error IOError 93 | end 94 | end 95 | 96 | context 'with an existing resource', :vcr do 97 | before { subject.add(url) } 98 | 99 | it 'gets an RDF::Enumerable' do 100 | expect(subject.retrieve(url)).to respond_to :each_statement 101 | end 102 | 103 | it 'raises IOError on invalid URL' do 104 | expect { subject.retrieve('http://example.com/moomin') } 105 | .to raise_error IOError 106 | end 107 | end 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /spec/support/shared_examples/schema.rb: -------------------------------------------------------------------------------- 1 | shared_examples 'a schema' do |properties| 2 | let(:fake_source) do 3 | klass = Class.new { include ActiveTriples::RDFSource } 4 | klass.apply_schema described_class 5 | klass 6 | end 7 | 8 | let(:source) { fake_source.new } 9 | let(:value) { :moomin } 10 | 11 | properties.each do |property| 12 | it "has configured property #{property}" do 13 | expect { source.send("#{property}=".to_sym, value) } 14 | .to change { source.send(property).to_a } 15 | .to contain_exactly(value) 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/vcr_setup.rb: -------------------------------------------------------------------------------- 1 | require 'webmock/rspec' 2 | require 'vcr' 3 | 4 | VCR.configure do |c| 5 | c.cassette_library_dir = 'spec/cassettes' 6 | c.hook_into :webmock 7 | c.configure_rspec_metadata! 8 | end -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ActiveTriples/linked-data-fragments/a30e627cd079104a7e867c412f0e1cf77dcbf025/vendor/assets/stylesheets/.keep --------------------------------------------------------------------------------