public function execute()
 {
     if (!class_exists('JsonSchema\\Uri\\UriRetriever')) {
         $this->error('The JsonSchema library cannot be found, please install it through composer.', 1);
     }
     $path = $this->getArg(0);
     $data = json_decode(file_get_contents($path));
     if (!is_object($data)) {
         $this->error("{$path} is not a valid JSON file.", 1);
     }
     if (!isset($data->manifest_version)) {
         $this->output("Warning: No manifest_version set, assuming 1.\n");
         // For backwards-compatability assume 1
         $data->manifest_version = 1;
     }
     $version = $data->manifest_version;
     if ($version !== ExtensionRegistry::MANIFEST_VERSION) {
         $schemaPath = dirname(__DIR__) . "/docs/extension.schema.v{$version}.json";
     } else {
         $schemaPath = dirname(__DIR__) . '/docs/extension.schema.json';
     }
     if ($version < ExtensionRegistry::OLDEST_MANIFEST_VERSION || $version > ExtensionRegistry::MANIFEST_VERSION) {
         $this->error("Error: {$path} is using a non-supported schema version, it should use " . ExtensionRegistry::MANIFEST_VERSION, 1);
     } elseif ($version < ExtensionRegistry::MANIFEST_VERSION) {
         $this->output("Warning: {$path} is using a deprecated schema, and should be updated to " . ExtensionRegistry::MANIFEST_VERSION . "\n");
     }
     $retriever = new JsonSchema\Uri\UriRetriever();
     $schema = $retriever->retrieve('file://' . $schemaPath);
     $validator = new JsonSchema\Validator();
     $validator->check($data, $schema);
     if ($validator->isValid()) {
         $this->output("{$path} validates against the version {$version} schema!\n");
     } else {
         foreach ($validator->getErrors() as $error) {
             $this->output("[{$error['property']}] {$error['message']}\n");
         }
         $this->error("{$path} does not validate.", 1);
     }
 }
 public function execute()
 {
     if (!class_exists('JsonSchema\\Uri\\UriRetriever')) {
         $this->error('The JsonSchema library cannot be found, please install it through composer.', 1);
     }
     $retriever = new JsonSchema\Uri\UriRetriever();
     $schema = $retriever->retrieve('file://' . dirname(__DIR__) . '/docs/extension.schema.json');
     $path = $this->getArg(0);
     $data = json_decode(file_get_contents($path));
     if (!is_object($data)) {
         $this->error("{$path} is not a valid JSON file.", 1);
     }
     $validator = new JsonSchema\Validator();
     $validator->check($data, $schema);
     if ($validator->isValid()) {
         $this->output("{$path} validates against the schema!\n");
     } else {
         foreach ($validator->getErrors() as $error) {
             $this->output("[{$error['property']}] {$error['message']}\n");
         }
         $this->error("{$path} does not validate.", 1);
     }
 }
 /**
  * @dataProvider providePassesValidation
  * @param string $path Path to thing's json file
  */
 public function testPassesValidation($path)
 {
     $data = json_decode(file_get_contents($path));
     $this->assertInstanceOf('stdClass', $data, "{$path} is not valid JSON");
     $this->assertObjectHasAttribute('manifest_version', $data, "{$path} does not have manifest_version set.");
     $version = $data->manifest_version;
     if ($version !== ExtensionRegistry::MANIFEST_VERSION) {
         $schemaPath = __DIR__ . "/../../../docs/extension.schema.v{$version}.json";
     } else {
         $schemaPath = __DIR__ . '/../../../docs/extension.schema.json';
     }
     // Not too old
     $this->assertTrue($version >= ExtensionRegistry::OLDEST_MANIFEST_VERSION, "{$path} is using a non-supported schema version");
     // Not too new
     $this->assertTrue($version <= ExtensionRegistry::MANIFEST_VERSION, "{$path} is using a non-supported schema version");
     $retriever = new JsonSchema\Uri\UriRetriever();
     $schema = $retriever->retrieve('file://' . $schemaPath);
     $validator = new JsonSchema\Validator();
     $validator->check($data, $schema);
     if ($validator->isValid()) {
         // All good.
         $this->assertTrue(true);
     } else {
         $out = "{$path} did pass validation.\n";
         foreach ($validator->getErrors() as $error) {
             $out .= "[{$error['property']}] {$error['message']}\n";
         }
         $this->assertTrue(false, $out);
     }
 }
 protected function beforeAction($action)
 {
     $reca = parent::beforeAction($action);
     return $reca;
     //check whether authenticated
     if (Yii::app()->request->isPostRequest) {
         //decode json
         try {
             $this->postData = json_decode(file_get_contents("php://input"));
         } catch (Exception $e) {
             throw new CHttpException(400, 'Bad request, invalid input format!');
         }
         //validate schema
         $validator = new JsonSchema\Validator();
         $validator->check($this->postData, ApiSchema::Schema(Yii::app()->controller->action->id));
         if (!$validator->isValid()) {
             $ret = '';
             foreach ($validator->getErrors() as $error) {
                 $ret .= '"' . $error['property'] . '" ' . $error['message'] . '<br />';
             }
             throw new CHttpException(401, 'Input data is invalid!');
         }
         //validate token
         if ($this->validateToken($this->postData->token)) {
             throw new CHttpException(402, 'Token is invalid!');
         }
     }
     return $reca;
 }
示例#5
0
 public function processString($jsonString)
 {
     if (empty($jsonString)) {
         return array('error' => 'Provide JSON file');
     }
     // Get the schema and data as objects
     $schema = $this->retriever->retrieve('file://' . __DIR__ . '/schema.json');
     $data = json_decode($jsonString);
     // If you use $ref or if you are unsure, resolve those references here
     // This modifies the $schema object
     $this->refResolver->resolve($schema, 'file://' . __DIR__);
     // Validate
     $validator = new \JsonSchema\Validator();
     $validator->check($data, $schema);
     $this->logger->info("Schema is: " . print_r($schema, 1));
     $this->logger->info("Data is: " . print_r($data, 1));
     $retArr = array();
     if ($validator->isValid()) {
         return true;
     } else {
         foreach ($validator->getErrors() as $error) {
             $retArr[$error['property']] = $error['message'];
             return $retArr;
         }
     }
 }
 public static function validate($data, $schema)
 {
     if (!is_null(json_decode($schema))) {
         $retriever = new \JsonSchema\Uri\UriRetriever();
         $validator = new \JsonSchema\Validator();
         $validator->check(json_decode($data), json_decode($schema));
         return $validator->isValid();
     }
     return true;
 }
示例#7
0
function validateAgainstSchema($schema_name, $data)
{
    $retriever = new JsonSchema\Uri\UriRetriever();
    $schema = $retriever->retrieve('file://' . __DIR__ . '/assets/' . $schema_name);
    $ref_resolver = new JsonSchema\RefResolver(new JsonSchema\Uri\UriRetriever());
    $ref_resolver->resolve($schema);
    $validator = new JsonSchema\Validator();
    $validator->check($data, $schema);
    return array('valid' => $validator->isValid(), 'errors' => $validator->getErrors());
}
示例#8
0
文件: Loader.php 项目: jingdor/pickle
 protected function validate($json)
 {
     $schema = json_decode(file_get_contents(__DIR__ . '/../../../../vendor/composer/composer/res/composer-schema.json'));
     $validator = new \JsonSchema\Validator();
     $validator->check($json, $schema);
     if (false === $validator->isValid()) {
         $message = '';
         foreach ($validator->getErrors() as $error) {
             $message .= sprintf('[%s] %s', $error['property'], $error['message']) . PHP_EOL;
         }
         throw new \RuntimeException($message);
     }
 }
 /**
  * @param Object $object the instance to validate against the json schema
  * @return mixed array containing errors or false
  */
 function check($object)
 {
     // recursively convert $object to a StdClass based structure
     // json-schema-php can only handle objects correctly - instead of assoc arrays
     // not scalable but thats not an issue here, data sets to validate are small.
     $object = json_decode(json_encode($object));
     $validator = new \JsonSchema\Validator();
     $validator->check($object, $this->schema);
     $errors = $validator->getErrors();
     if (empty($errors)) {
         return false;
     }
     return $errors;
 }
 public function validate(\stdClass $json)
 {
     $retriever = new \JsonSchema\Uri\UriRetriever();
     $validator = new \JsonSchema\Validator();
     $resource = $this->schemafilepath;
     if (strpos($resource, ':') === false && file_exists($resource)) {
         $resource = "file://{$resource}";
     }
     $validator->check($json, $retriever->retrieve($resource));
     if (!$validator->isValid()) {
         throw new ValidationException('JSON does not validate', $validator);
     }
     return true;
 }
 public static function validate($data, $schemaFile = '')
 {
     if (\Config::get('json-schema-validator::config.run') === false) {
         return true;
     }
     if (!empty($schemaFile)) {
         $retriever = new \JsonSchema\Uri\UriRetriever();
         $path = \Config::get('json-schema-validator::config.schemaDir') . '/response/' . $schemaFile;
         $schema = $retriever->retrieve('file://' . $path);
         $validator = new \JsonSchema\Validator();
         $validator->check($data, $schema);
         return $validator->isValid();
     }
     return true;
 }
 public function validate_json($json, $schemas_name, $schemas_path)
 {
     $retriever = new JsonSchema\Uri\UriRetriever();
     $json_schemas = $retriever->retrieve('file://' . $schemas_path . "/{$schemas_name}");
     $refResolver = new JsonSchema\RefResolver($retriever);
     $refResolver->resolve($json_schemas, 'file://' . $schemas_path . "/");
     $validator = new JsonSchema\Validator();
     $validator->check($json, $json_schemas);
     if ($validator->isValid()) {
         return false;
     }
     $details = "";
     foreach ($validator->getErrors() as $error) {
         $details .= sprintf("[%s] %s\n", $error['property'], $error['message']);
     }
     return $details;
 }
示例#13
0
 /**
  * {@inheritDoc}
  */
 public function validate($data, Constraint $constraint)
 {
     if (!is_object($data) || !$data instanceof UploadedFile) {
         throw new InvalidArgumentException(sprintf('This validator expects a UploadedFile, given "%s"', get_class($data)));
     }
     $composerData = json_decode(file_get_contents($data->openFile()->getRealPath()));
     $schema = $this->getSchema($constraint->getSchemaPath());
     // In version 1.1.0 of the validator, "required" attributes are not used.
     // So data structure might be partially unset.
     $validator = new \JsonSchema\Validator();
     $validator->check($composerData, $schema);
     if (!$validator->isValid()) {
         $this->context->addViolation("Invalid composer.lock file given:");
     }
     foreach ($validator->getErrors() as $error) {
         $this->context->addViolation(sprintf("[%s] %s\n", $error['property'], $error['message']));
     }
 }
function validate_user_data($user_data)
{
    global $user_schema;
    $result = false;
    $temp = json_encode($user_data);
    $user_data = json_decode($temp);
    // Validate
    $validator = new JsonSchema\Validator();
    $validator->check($user_data, $user_schema);
    if ($validator->isValid()) {
        $result = true;
    } else {
        echo "JSON does not validate. Violations:\n";
        foreach ($validator->getErrors() as $error) {
            echo sprintf("[%s] %s\n", $error['property'], $error['message']);
        }
    }
    return $result;
}
示例#15
0
 /**
  *  Validate response by json schema
  *
  *  @param string $schema path to json schema file
  */
 public function canSeeResponseIsValidOnSchemaFile($schema)
 {
     $schemaPath = realpath($schema);
     $retriever = new \JsonSchema\Uri\UriRetriever();
     $schema = $retriever->retrieve('file://' . $schemaPath);
     $refResolver = new \JsonSchema\RefResolver($retriever);
     $refResolver->resolve($schema, 'file://' . $schemaPath);
     $response = $this->getModule('REST')->response;
     $validator = new \JsonSchema\Validator();
     $validator->setUriRetriever(new UriRetriever());
     $validator->check(json_decode($response), $schema);
     $message = '';
     $isValid = $validator->isValid();
     if (!$isValid) {
         $message = "JSON does not validate. Violations:\n";
         foreach ($validator->getErrors() as $error) {
             $message .= $error['property'] . " " . $error['message'] . PHP_EOL;
         }
     }
     $this->assertTrue($isValid, $message);
 }
function validate_poi_data($poi_data)
{
    $result = false;
    $poi_schema = load_poi_schema();
    //     var_dump($poi_schema);
    $intl_props = find_intl_properties($poi_schema->properties);
    //var_dump($intl_props);
    $temp = json_encode($poi_data);
    $poi_data = json_decode($temp);
    // Validate
    $validator = new JsonSchema\Validator();
    $validator->check($poi_data, $poi_schema);
    if ($validator->isValid()) {
        //         echo "The supplied JSON validates against the schema.\n";
        $result = true;
    } else {
        echo "JSON does not validate. Violations:\n";
        foreach ($validator->getErrors() as $error) {
            echo sprintf("[%s] %s\n", $error['property'], $error['message']);
        }
    }
    return $result;
}
 public function jsonschema_validator($data, $schema = null, $chunked = null)
 {
     if ($data) {
         $schema_variant = !empty($schema) ? "{$schema}/" : "";
         $schema_module = $schema == 'federal-v1.1' && $chunked == true ? 'dataset.json' : 'catalog.json';
         $path = './schema/' . $schema_variant . $schema_module;
         //echo $path; exit;
         // Get the schema and data as objects
         $retriever = new JsonSchema\Uri\UriRetriever();
         $schema = $retriever->retrieve('file://' . realpath($path));
         //header('Content-type: application/json');
         //print $data;
         //exit;
         $data = json_decode($data);
         if (!empty($data)) {
             // If you use $ref or if you are unsure, resolve those references here
             // This modifies the $schema object
             $refResolver = new JsonSchema\RefResolver($retriever);
             $refResolver->resolve($schema, 'file://' . __DIR__ . '/../../schema/' . $schema_variant);
             // Validate
             $validator = new JsonSchema\Validator();
             $validator->check($data, $schema);
             if ($validator->isValid()) {
                 $results = array('valid' => true, 'errors' => false);
             } else {
                 $errors = $validator->getErrors();
                 $results = array('valid' => false, 'errors' => $errors);
             }
             //header('Content-type: application/json');
             //print json_encode($results);
             //exit;
             return $results;
         } else {
             return false;
         }
     }
 }
示例#18
0
 /**
  * Validates JSON schema.
  *
  * @throws DecodeException
  *
  * @return void
  */
 protected function validateSchema()
 {
     $schemaPath = $this->getOption('schemaPath');
     if ($schemaPath === null) {
         return;
     }
     $schemaData = json_decode(file_get_contents($schemaPath));
     if (!class_exists('\\JsonSchema\\Validator')) {
         throw new \RuntimeException('If you want to validate a JSON schema, you must require package "justinrainbow/json-schema"-');
     }
     $validator = new \JsonSchema\Validator();
     $validator->check($this->getContents(), $schemaData);
     if (!$validator->isValid()) {
         $errors = [];
         foreach ((array) $validator->getErrors() as $error) {
             $errors[] = ($error['property'] ? $error['property'] . ' : ' : '') . $error['message'];
         }
         throw DecodeException::create($this->getPath(), ['errors' => $errors]);
     }
 }
 /**
  * TO DO - when agencies provide a valid url, we should validate that before
  * the download.
  *
  * Open the archived file that has been downloaded in campaign status method and
  * validate it against the schema
  *
  * @param <array> $status
  * @param <string> $file_path
  * @param <string> $component
  * @param <string> $real_url
  */
 public function validate_archive_file_with_schema($status, $file_path, $component, $real_url)
 {
     $fp = fopen($file_path, 'r');
     if (!$fp) {
         $status['errors'][] = "Unable to open archived json file";
     }
     $status['total_records'] = 0;
     $status['download_content_length'] = 0;
     $status['content_type'] = "application/json";
     $status['schema_version'] = "1.0";
     $json = file_get_contents($file_path);
     if (empty($json)) {
         $status['errors'][] = 'Archived json file is empty';
         $status['valid_json'] = false;
     } else {
         if (!is_json($json)) {
             $json = json_text_filter($json);
         }
     }
     if (!empty($json) && !is_json($json)) {
         $status['errors'][] = 'Invalid archived json file';
         $status['valid_json'] = false;
     } else {
         $status['download_content_length'] = strlen($json);
         $data = json_decode($json);
         $status['total_records'] = count($data);
         $status['valid_json'] = true;
     }
     $schema = $this->datajson_schema($component);
     if (!empty($data)) {
         $validator = new JsonSchema\Validator();
         $validator->check($data, $schema);
         if (!$validator->isValid()) {
             $errors = $validator->getErrors();
             $status['schema_errors'] = $errors;
         }
     }
     return $status;
 }
 /**
  * Validate specified array of data against json-schema and returns the validation result.
  *
  * @param array $args
  * @return ValidationResult
  */
 public function validate($args)
 {
     $result = array('is_valid' => false, 'messages' => array());
     $validator = new \JsonSchema\Validator();
     $obj = (object) $args['request'];
     $json_schema_path = $this->options['json_schema_dir'] . $args['json_schema'];
     $json_schema = json_decode(file_get_contents($json_schema_path));
     $validator->check($obj, $json_schema);
     if (!$validator->isValid()) {
         if (isset($args['json_message'])) {
             $json_message_path = $this->options['json_message_dir'] . $args['json_message'];
             $json_message = json_decode(file_get_contents($json_message_path));
             /* @var $json_message \stdClass */
         }
         if (isset($this->options['default_json_message'])) {
             $json_default_message_path = $this->options['json_message_dir'] . $this->options['default_json_message'];
             $json_default_message = json_decode(file_get_contents($json_default_message_path));
             /* @var $json_message \stdClass */
         }
         $result['messages'] = array();
         foreach ($validator->getErrors() as $error) {
             $property = $error['property'];
             $constraint = $error['constraint'];
             $message = $error['message'];
             $result['messages'][$property][$constraint] = array('message' => $property . ' ' . $message);
             // if custom message is specified
             // let's use custom message
             if (isset($json_message)) {
                 try {
                     $custom_message = @$json_message->{$property}->messages->{$constraint};
                 } catch (\Exception $e) {
                 }
                 if ($custom_message) {
                     //
                     // Find & replace the variables in the custom message
                     //
                     $find = array('{{ label }}');
                     $replace = array($json_message->{$property}->label);
                     foreach ($error as $key => $val) {
                         $find[] = "{{ schema.{$key} }}";
                         $replace[] = $val;
                     }
                     $custom_message = str_replace($find, $replace, $custom_message);
                     $result['messages'][$property][$constraint] = array('message' => $custom_message);
                 } else {
                     if (isset($json_default_message) && $json_default_message) {
                         try {
                             $custom_message = @$json_default_message->messages->{$constraint};
                         } catch (\Exception $e) {
                         }
                         if ($custom_message) {
                             //
                             // Find & replace the variables in the custom message
                             //
                             $find = array();
                             $replace = array();
                             foreach ($error as $key => $val) {
                                 $find[] = "{{ schema.{$key} }}";
                                 $replace[] = $val;
                             }
                             $custom_message = str_replace($find, $replace, $custom_message);
                             $result['messages'][$property][$constraint] = array('message' => $custom_message);
                         }
                     }
                 }
             }
         }
     } else {
         $result['is_valid'] = true;
     }
     return new ValidationResult($result);
 }
示例#21
0
$returnmessage = new stdClass();
$jsonpostbody = file_get_contents('php://input');
// check query is not empty
if (empty($jsonpostbody)) {
    $returnmessage->error = "POST body is empty";
} else {
    //convert json string to json object
    $data = json_decode($jsonpostbody);
    if (is_null($data)) {
        $returnmessage->error = "JSON does not decode";
    } else {
        // load json-schema for PHP (https://github.com/justinrainbow/json-schema)
        require __DIR__ . '/vendor/autoload.php';
        $retriever = new JsonSchema\Uri\UriRetriever();
        $schema = $retriever->retrieve('file://' . realpath($schemafile));
        $validator = new JsonSchema\Validator();
        $validator->check($data, $schema);
        // validate against schema
        if (!$validator->isValid()) {
            $returnmessage->error = "JSON does not validate to schema (serverside):";
            foreach ($validator->getErrors() as $error) {
                $returnmessage->error .= " " . $error['message'] . ';';
            }
        } else {
            // restringify the json object and get crc of the string
            $jsonstring = json_encode($data);
            $hash = dechex(crc32($jsonstring));
            $filename = $savefolder . '/' . $hash . '.json';
            $file = './' . $filename;
            // check file already exists and if not store
            if (!file_exists($file)) {
示例#22
0
 private function loadMonorepoJson($contents, $path)
 {
     $schema = json_decode(file_get_contents(__DIR__ . '/../../resources/monorepo-schema.json'));
     $data = json_decode($contents);
     // Validate
     $validator = new \JsonSchema\Validator();
     $validator->check($data, $schema);
     if (!$validator->isValid()) {
         $errors = array();
         foreach ($validator->getErrors() as $error) {
             $errors[] = sprintf("[%s] %s\n", $error['property'], $error['message']);
         }
         throw new \RuntimeException(sprintf("JSON is not valid in %s\n%s", $path, implode("\n", $errors)));
     }
     return json_decode($contents, true);
 }
示例#23
0
 /**
  * Validate Settings against Schema
  *
  */
 public function _validate()
 {
     if (!class_exists('JsonSchema\\Validator')) {
         return;
     }
     $validator = new \JsonSchema\Validator();
     // Process Validation.
     $validator->check($this->_data, $this->_schema);
     if ($validator->isValid()) {
         $this->is_valid = true;
         $this->_console("The supplied JSON validates against the schema.");
     } else {
         $this->is_valid = false;
         $this->_console("JSON does not validate. Violations:");
         foreach ($validator->getErrors() as $error) {
             $this->_console(sprintf("[%s] %s\n", $error['property'], $error['message']));
         }
     }
 }
示例#24
0
<?php

require './vendor/autoload.php';
$schema = file_get_contents('./schemas/books.json');
$json = file_get_contents('php://stdin');
$validator = new JsonSchema\Validator();
$validator->check(json_decode($json), json_decode($schema));
if ($validator->isValid()) {
    echo "The supplied JSON validates against the schema.\n";
} else {
    echo "JSON does not validate. Violations:\n";
    foreach ($validator->getErrors() as $error) {
        echo sprintf("[%s] %s\n", $error['property'], $error['message']);
    }
}
示例#25
0
<?php

require __DIR__ . '/../vendor/autoload.php';
$data = json_decode(file_get_contents('data.json'));
// Validate
$validator = new JsonSchema\Validator();
$validator->check($data, (object) ['$ref' => 'file://' . realpath('schema.json')]);
if ($validator->isValid()) {
    echo "The supplied JSON validates against the schema.\n";
} else {
    echo "JSON does not validate. Violations:\n";
    foreach ($validator->getErrors() as $error) {
        echo sprintf("[%s] %s\n", $error['property'], $error['message']);
    }
}
示例#26
-2
 public function checkRequest()
 {
     $retriever = new JsonSchema\Uri\UriRetriever();
     #$path = realpath('schemas/post_call.json');
     $path = realpath($this->getSchemaPath());
     $schema = $retriever->retrieve('file://' . $path);
     $refResolver = new JsonSchema\RefResolver($retriever);
     $refResolver->resolve($schema, 'file://' . __DIR__);
     $validator = new JsonSchema\Validator();
     $data = json_decode(file_get_contents("php://input"));
     $validator->check($data, $schema);
     if ($validator->isValid()) {
         $this->valid = true;
         $this->params = (array) $data->request;
         $this->action = $data->request->action;
     } else {
         $this->errors = ["JSON does not validate"];
         foreach ($validator->getErrors() as $error) {
             array_push($this->errors, sprintf("[%s] %s\n", $error['property'], $error['message']));
         }
     }
 }
 function _testComposerJSONSchema($filename)
 {
     // Get the schema and data as objects
     $retriever = new \JsonSchema\Uri\UriRetriever();
     $schema = $retriever->retrieve("file://" . __DIR__ . "/../composer-schema.json");
     $data = json_decode(file_get_contents($filename));
     // // If you use $ref or if you are unsure, resolve those references here
     // // This modifies the $schema object
     // $refResolver = new JsonSchema\RefResolver($retriever);
     // $refResolver->resolve($schema, 'file://' . __DIR__);
     // Validate
     $validator = new \JsonSchema\Validator();
     $validator->check($data, $schema);
     $message = "(no message)";
     $errors = $validator->getErrors();
     if (count($errors) > 0) {
         $message = trim($errors[0]['property'] . " " . $errors[0]['message']);
     }
     if (!$validator->isValid() && $this->printComposerJSONSchemaErrors()) {
         foreach ($validator->getErrors() as $error) {
             echo sprintf("[%s] %s\n", $error['property'], $error['message']);
         }
     }
     $this->assertTrue($validator->isValid(), "File '{$filename}' was not valid Composer JSON according to composer-schema.json: {$message}");
 }